From b3cc581826e5726cbfd350ab40fa53618b554d57 Mon Sep 17 00:00:00 2001 From: Christian Sadilek Date: Thu, 11 Aug 2016 16:41:48 -0400 Subject: [PATCH] UF-317: Dynamic GWT plugin support (details below) (#464) Enhance run-time plugin mechanism to support client-side plugin development using the GWT/Errai/UberFire programming model. This has been a long time coming with the lion's share of the work in Errai (IOC/CDI support for JS types) and GWT (JsInterop) respectively. UberFire enhancements: - Add minimal new API surface to mark perspectives, screens, and editors as dynamic - Refactor Activity class hierarchy and related types to allow sharing of these types across different scripts using JsInterop - Mark types as @JsTypes were possible to export method names (need stable method names across different compilation units) - Add @JsIgnore to methods that can't be exported because they use parameter or return types that can't be used from JavaScript e.g. widgets - Provide and use alternative default methods usable from JS where possible - Disable managed beans on classpath that are not needed in plugins based on system property - Monitor the /plugins dir for .jar files, extract them and publish the contained JS files - Load plugins using Errai's ScriptRegistry and ScriptInjectionFilter to ensure all plugin scripts are executed before the actual app bootstraps (required to make sure all plugins and its managed beans can be discovered by the main application) - Enhance uberfire-showcase to demonstrate this new plugin functionality (see README.md in uberfire-showcase/ uberfire-dynamic-plugin for details) - Add test coverage for client-side dynamic activity generation, server-side plugin monitoring and processing --- .../uberfire/backend/vfs/ObservablePath.java | 2 + .../java/org/uberfire/backend/vfs/Path.java | 3 + .../backend/vfs/impl/ObservablePathImpl.java | 2 +- .../main/java/org/uberfire/mvp/Command.java | 3 + .../java/org/uberfire/mvp/PlaceRequest.java | 21 +- .../mvp/impl/DefaultPlaceRequest.java | 2 +- .../mvp/impl/ExternalPathPlaceRequest.java | 45 ++++ .../uberfire/mvp/impl/PathPlaceRequest.java | 1 + .../java/org/uberfire/plugin/PluginUtil.java | 97 ++++++++ .../java/org/uberfire/security/Resource.java | 28 ++- .../org/uberfire/security/ResourceAction.java | 3 + .../org/uberfire/security/ResourceType.java | 3 + .../security/authz/ResourceActionRef.java | 8 + .../security/authz/RuntimeResource.java | 3 + .../workbench/events/PluginAddedEvent.java | 29 +++ .../workbench/events/PluginEvent.java | 29 +++ .../workbench/events/PluginUpdatedEvent.java | 29 +++ .../events/PluginsReloadedEvent.java | 24 ++ .../workbench/model/ActivityResourceType.java | 3 + .../workbench/model/CompassPosition.java | 3 + .../workbench/model/ContextDefinition.java | 3 + .../workbench/model/ContextDisplayMode.java | 3 + .../workbench/model/PanelDefinition.java | 80 +++++++ .../workbench/model/PartDefinition.java | 10 + .../model/PerspectiveDefinition.java | 3 + .../uberfire/workbench/model/Position.java | 3 + .../model/impl/PanelDefinitionImpl.java | 21 +- .../model/impl/PartDefinitionImpl.java | 2 +- .../menu/EnabledStateChangeListener.java | 3 + .../menu/HasEnabledStateChangeListeners.java | 3 + .../workbench/model/menu/MenuCustom.java | 3 + .../workbench/model/menu/MenuGroup.java | 3 + .../workbench/model/menu/MenuItem.java | 24 +- .../workbench/model/menu/MenuItemCommand.java | 3 + .../model/menu/MenuItemPerspective.java | 3 + .../workbench/model/menu/MenuItemPlain.java | 3 + .../workbench/model/menu/MenuPosition.java | 3 + .../workbench/model/menu/MenuVisitor.java | 8 + .../uberfire/workbench/model/menu/Menus.java | 3 + .../model/menu/impl/BaseMenuCustom.java | 8 +- .../model/menu/impl/DefaultMenuGroup.java | 151 ++++++++++++ .../model/menu/impl/DefaultMenus.java | 77 ++++++ .../model/menu/impl/MenuBuilderImpl.java | 124 +--------- .../workbench/model/toolbar/ToolBar.java | 3 + .../workbench/model/toolbar/ToolBarIcon.java | 3 + .../workbench/model/toolbar/ToolBarItem.java | 4 +- .../model/toolbar/impl/DefaultToolBar.java | 9 +- .../type/ResourceTypeDefinition.java | 3 + .../org/uberfire/UberfireAPI.gwt.xml | 1 + .../model/impl/PanelDefinitionImplTest.java | 8 +- ...Service.java => RuntimePluginService.java} | 2 +- .../uberfire-backend-server/pom.xml | 5 + .../server/plugin/GwtRuntimePluginLoader.java | 188 +++++++++++++++ .../plugin/GwtRuntimePluginManager.java | 147 ++++++++++++ .../plugin/GwtRuntimePluginWatcher.java | 136 +++++++++++ .../backend/server/plugin/PluginRegistry.java | 60 +++++ .../plugin/PluginServletContextListener.java | 42 ++++ ...mpl.java => RuntimePluginServiceImpl.java} | 60 ++++- .../security/FileSystemResourceAdaptor.java | 6 +- .../plugin/AbstractGwtRuntimePluginTest.java | 42 ++++ .../plugin/GwtRuntimePluginLoaderTest.java | 129 ++++++++++ .../plugin/GwtRuntimePluginManagerTest.java | 114 +++++++++ .../plugin/GwtRuntimePluginWatcherTest.java | 80 +++++++ .../src/test/resources/plugins/plugin.txt | 1 + .../resources/test-app/test-app.nocache.js | 1 + .../client/annotations/WorkbenchEditor.java | 8 + .../annotations/WorkbenchPerspective.java | 13 +- .../client/annotations/WorkbenchScreen.java | 8 + .../org/uberfire/client/mvp/LockTarget.java | 13 +- .../workbench/type/ClientResourceType.java | 12 +- .../commons/client/history/SaveButton.java | 11 +- .../client/history/VersionMenuItem.java | 6 +- .../client/RuntimePluginsEntryPoint.java | 2 + .../generator/PerspectiveEditorActivity.java | 15 +- .../PerspectiveEditorScreenActivity.java | 20 +- .../org/uberfire/client/JSEntryPoint.java | 2 + .../client/editor/JSEditorActivity.java | 5 +- .../uberfire/client/jsapi/JSPlaceRequest.java | 4 +- .../screen/JSWorkbenchScreenActivity.java | 18 +- .../client/splash/JSSplashScreenActivity.java | 5 +- .../authz/DefaultAuthorizationManager.java | 3 +- .../impl/authz/DefaultPermissionManager.java | 2 +- .../impl/authz/DotNamedPermissionType.java | 2 +- ...FastCompiledUberfireShowcaseClient.gwt.xml | 3 + .../uberfire/UberfireShowcaseClient.gwt.xml | 4 + .../uberfire-dynamic-plugin/.gitignore | 17 ++ .../uberfire-dynamic-plugin/README.md | 38 +++ .../uberfire-dynamic-plugin/pom.xml | 127 ++++++++++ .../client/editor/DynamicEditorPresenter.java | 46 ++++ .../client/editor/DynamicEditorView.html | 6 + .../client/editor/DynamicEditorView.java | 18 ++ .../perspective/DynamicPerspective.java | 95 ++++++++ .../client/screen/DynamicResourceType.java | 64 +++++ .../uberfire/client/screen/DynamicScreen.html | 21 ++ .../uberfire/client/screen/DynamicScreen.java | 52 +++++ .../src/main/resources/ErraiApp.properties | 1 + .../src/main/resources/META-INF/beans.xml | 6 + .../uberfire/UberfireDynamicPlugin.gwt.xml | 36 +++ .../src/main/webapp/dynamic-plugin.html | 28 +++ uberfire-showcase/uberfire-webapp/pom.xml | 9 +- .../uberfire/client/ShowcaseEntryPoint.java | 40 +++- .../client/screens/SampleWorkbenchEditor.java | 3 +- .../client/screens/TextResourceType.java | 64 +++++ .../org/uberfire/UberfireShowcase.gwt.xml | 4 + .../src/main/webapp/WEB-INF/web.xml | 8 +- .../main/webapp/{showcase.html => index.html} | 2 +- ...RuntimePluginsServiceProxyBackendImpl.java | 4 +- .../views/pfly/listbar/ListBarWidgetImpl.java | 5 +- .../views/pfly/listbar/PartListDropdown.java | 2 +- .../pfly/toolbar/WorkbenchToolBarView.java | 4 +- .../views/pfly/mock/MockPlaceManager.java | 5 + .../client/menu/AuthFilterMenuVisitor.java | 7 +- .../uberfire/client/mvp/AbstractActivity.java | 6 +- .../mvp/AbstractSplashScreenActivity.java | 5 - .../client/mvp/AbstractWorkbenchActivity.java | 10 - .../mvp/AbstractWorkbenchEditorActivity.java | 35 +-- .../AbstractWorkbenchPerspectiveActivity.java | 3 +- .../org/uberfire/client/mvp/Activity.java | 34 ++- .../client/mvp/ActivityBeansCache.java | 36 +-- .../client/mvp/ActivityManagerImpl.java | 11 +- .../uberfire/client/mvp/ActivityMetaInfo.java | 46 +++- .../org/uberfire/client/mvp/LockManager.java | 3 + .../client/mvp/PerspectiveActivity.java | 8 + .../client/mvp/PerspectiveManagerImpl.java | 10 +- .../org/uberfire/client/mvp/PlaceManager.java | 47 +++- .../uberfire/client/mvp/PlaceManagerImpl.java | 105 ++++++--- .../org/uberfire/client/mvp/PlaceStatus.java | 3 + .../client/mvp/PluginActivityManagerImpl.java | 112 +++++++++ .../client/mvp/PluginPlaceManagerImpl.java | 221 ++++++++++++++++++ .../client/mvp/SplashScreenActivity.java | 9 +- .../client/mvp/WorkbenchActivity.java | 30 ++- .../client/mvp/WorkbenchEditorActivity.java | 7 + .../client/workbench/PanelManagerImpl.java | 31 +-- .../client/workbench/PluginEntryPoint.java | 45 ++++ .../StandaloneEditorPerspective.java | 4 +- .../uberfire/client/workbench/Workbench.java | 17 +- .../client/workbench/WorkbenchLayout.java | 1 - ...bstractDockingWorkbenchPanelPresenter.java | 7 +- .../AbstractDockingWorkbenchPanelView.java | 5 +- .../impl/AbstractWorkbenchPanelPresenter.java | 9 +- .../impl/AdaptiveWorkbenchPanelPresenter.java | 2 +- .../panels/impl/SplitLayoutPanelView.java | 4 +- .../widgets/dnd/CompassDropController.java | 2 +- .../dnd/WorkbenchPickupDragController.java | 9 +- .../menu/WorkbenchMenuBarPresenter.java | 9 +- .../notfound/ActivityNotFoundPresenter.java | 5 +- .../client/mvp/AbstractPopupActivityTest.java | 12 +- .../ActivityBeansCacheActivatedByTest.java | 2 +- .../ActivityBeansCacheUnitTestWrapper.java | 6 +- .../mvp/ActivityManagerActivatedByTest.java | 2 +- .../client/mvp/ActivityMetaInfoTest.java | 54 +++-- .../PlaceRequestHistoryMapperImplTest.java | 3 +- .../mvp/WorkbenchEditorActivityTest.java | 54 ++++- .../workbench/WorkbenchStartupTest.java | 16 +- .../panels/impl/PlaceManagerTest.java | 72 ++++-- .../menu/WorkbenchMenuBarPresenterTest.java | 23 +- .../processors/PerspectiveProcessorTest.java | 19 ++ .../WorkbenchEditorProcessorTest.java | 18 ++ .../WorkbenchPopupProcessorTest.java | 36 +-- .../WorkbenchScreenProcessorTest.java | 53 +++-- .../processors/PerspectiveTest24.java | 15 ++ .../processors/WorkbenchEditorTest28.java | 29 +++ .../processors/WorkbenchScreenTest29.java | 2 +- .../processors/WorkbenchScreenTest33.java | 26 +++ .../WorkbenchSplashScreenTest6.java | 2 +- .../expected/PerspectiveTest10.expected | 2 +- .../expected/PerspectiveTest11.expected | 1 + .../expected/PerspectiveTest20.expected | 1 + .../expected/PerspectiveTest21.expected | 1 + .../expected/PerspectiveTest24.expected | 68 ++++++ .../expected/PerspectiveTest4.expected | 1 + .../expected/PerspectiveTest5.expected | 1 + .../expected/PerspectiveTest6.expected | 1 + .../expected/PerspectiveTest7.expected | 1 + .../expected/PerspectiveTest8.expected | 1 + .../expected/PerspectiveTest9.expected | 1 + .../expected/WorkbenchEditorTest22.expected | 4 +- .../expected/WorkbenchEditorTest24.expected | 2 +- .../expected/WorkbenchEditorTest26.expected | 2 +- .../expected/WorkbenchEditorTest28.expected | 92 ++++++++ .../expected/WorkbenchScreenTest24.expected | 2 +- .../expected/WorkbenchScreenTest26.expected | 2 +- .../expected/WorkbenchScreenTest28.expected | 4 +- .../expected/WorkbenchScreenTest29.expected | 2 +- .../expected/WorkbenchScreenTest33.expected | 90 +++++++ .../WorkbenchSplashScreenTest6.expected | 1 + .../WorkbenchSplashScreenTest7.expected | 1 + .../WorkbenchSplashScreenTest9.expected | 1 + .../processors/EditorActivityGenerator.java | 7 +- .../PerspectiveActivityGenerator.java | 3 + .../processors/ScreenActivityGenerator.java | 3 + .../processors/facades/ClientAPIModule.java | 18 ++ .../processors/templates/activityEditor.ftl | 78 ++++--- .../processors/templates/activityScreen.ftl | 38 ++- .../processors/templates/perspective.ftl | 39 ++-- .../processors/templates/popupScreen.ftl | 24 +- .../processors/templates/splashScreen.ftl | 26 ++- 197 files changed, 4049 insertions(+), 598 deletions(-) create mode 100644 uberfire-api/src/main/java/org/uberfire/mvp/impl/ExternalPathPlaceRequest.java create mode 100644 uberfire-api/src/main/java/org/uberfire/plugin/PluginUtil.java create mode 100644 uberfire-api/src/main/java/org/uberfire/workbench/events/PluginAddedEvent.java create mode 100644 uberfire-api/src/main/java/org/uberfire/workbench/events/PluginEvent.java create mode 100644 uberfire-api/src/main/java/org/uberfire/workbench/events/PluginUpdatedEvent.java create mode 100644 uberfire-api/src/main/java/org/uberfire/workbench/events/PluginsReloadedEvent.java create mode 100644 uberfire-api/src/main/java/org/uberfire/workbench/model/menu/impl/DefaultMenuGroup.java create mode 100644 uberfire-api/src/main/java/org/uberfire/workbench/model/menu/impl/DefaultMenus.java rename uberfire-backend/uberfire-backend-api/src/main/java/org/uberfire/backend/plugin/{RuntimePluginsService.java => RuntimePluginService.java} (95%) create mode 100644 uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugin/GwtRuntimePluginLoader.java create mode 100644 uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugin/GwtRuntimePluginManager.java create mode 100644 uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugin/GwtRuntimePluginWatcher.java create mode 100644 uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugin/PluginRegistry.java create mode 100644 uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugin/PluginServletContextListener.java rename uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugin/{RuntimePluginsServiceServerImpl.java => RuntimePluginServiceImpl.java} (61%) create mode 100644 uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/plugin/AbstractGwtRuntimePluginTest.java create mode 100644 uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/plugin/GwtRuntimePluginLoaderTest.java create mode 100644 uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/plugin/GwtRuntimePluginManagerTest.java create mode 100644 uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/plugin/GwtRuntimePluginWatcherTest.java create mode 100644 uberfire-backend/uberfire-backend-server/src/test/resources/plugins/plugin.txt create mode 100644 uberfire-backend/uberfire-backend-server/src/test/resources/test-app/test-app.nocache.js create mode 100644 uberfire-showcase/uberfire-dynamic-plugin/.gitignore create mode 100644 uberfire-showcase/uberfire-dynamic-plugin/README.md create mode 100644 uberfire-showcase/uberfire-dynamic-plugin/pom.xml create mode 100644 uberfire-showcase/uberfire-dynamic-plugin/src/main/java/org/uberfire/client/editor/DynamicEditorPresenter.java create mode 100644 uberfire-showcase/uberfire-dynamic-plugin/src/main/java/org/uberfire/client/editor/DynamicEditorView.html create mode 100644 uberfire-showcase/uberfire-dynamic-plugin/src/main/java/org/uberfire/client/editor/DynamicEditorView.java create mode 100644 uberfire-showcase/uberfire-dynamic-plugin/src/main/java/org/uberfire/client/perspective/DynamicPerspective.java create mode 100644 uberfire-showcase/uberfire-dynamic-plugin/src/main/java/org/uberfire/client/screen/DynamicResourceType.java create mode 100644 uberfire-showcase/uberfire-dynamic-plugin/src/main/java/org/uberfire/client/screen/DynamicScreen.html create mode 100644 uberfire-showcase/uberfire-dynamic-plugin/src/main/java/org/uberfire/client/screen/DynamicScreen.java create mode 100644 uberfire-showcase/uberfire-dynamic-plugin/src/main/resources/ErraiApp.properties create mode 100644 uberfire-showcase/uberfire-dynamic-plugin/src/main/resources/META-INF/beans.xml create mode 100644 uberfire-showcase/uberfire-dynamic-plugin/src/main/resources/org/uberfire/UberfireDynamicPlugin.gwt.xml create mode 100644 uberfire-showcase/uberfire-dynamic-plugin/src/main/webapp/dynamic-plugin.html create mode 100644 uberfire-showcase/uberfire-webapp/src/main/java/org/uberfire/client/screens/TextResourceType.java rename uberfire-showcase/uberfire-webapp/src/main/webapp/{showcase.html => index.html} (100%) create mode 100644 uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/PluginActivityManagerImpl.java create mode 100644 uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/PluginPlaceManagerImpl.java create mode 100644 uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/PluginEntryPoint.java create mode 100644 uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/PerspectiveTest24.java create mode 100644 uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/WorkbenchEditorTest28.java create mode 100644 uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/WorkbenchScreenTest33.java create mode 100644 uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest24.expected create mode 100644 uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchEditorTest28.expected create mode 100644 uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchScreenTest33.expected diff --git a/uberfire-api/src/main/java/org/uberfire/backend/vfs/ObservablePath.java b/uberfire-api/src/main/java/org/uberfire/backend/vfs/ObservablePath.java index bc20f974c5..ce65768040 100644 --- a/uberfire-api/src/main/java/org/uberfire/backend/vfs/ObservablePath.java +++ b/uberfire-api/src/main/java/org/uberfire/backend/vfs/ObservablePath.java @@ -41,6 +41,8 @@ public interface ObservablePath extends Path, void onConcurrentCopy( final ParameterizedCommand command ); ObservablePath wrap( final Path path ); + + Path getOriginal(); public interface OnConcurrentUpdateEvent extends SessionInfo { diff --git a/uberfire-api/src/main/java/org/uberfire/backend/vfs/Path.java b/uberfire-api/src/main/java/org/uberfire/backend/vfs/Path.java index adc03a741c..068082cf4d 100644 --- a/uberfire-api/src/main/java/org/uberfire/backend/vfs/Path.java +++ b/uberfire-api/src/main/java/org/uberfire/backend/vfs/Path.java @@ -16,6 +16,9 @@ package org.uberfire.backend.vfs; +import jsinterop.annotations.JsType; + +@JsType public interface Path extends Comparable { String getFileName(); diff --git a/uberfire-api/src/main/java/org/uberfire/backend/vfs/impl/ObservablePathImpl.java b/uberfire-api/src/main/java/org/uberfire/backend/vfs/impl/ObservablePathImpl.java index eddfd575d6..757c6a3b07 100644 --- a/uberfire-api/src/main/java/org/uberfire/backend/vfs/impl/ObservablePathImpl.java +++ b/uberfire-api/src/main/java/org/uberfire/backend/vfs/impl/ObservablePathImpl.java @@ -80,7 +80,7 @@ public ObservablePath wrap( final Path path ) { // 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. - private Path getOriginal() { + public Path getOriginal() { if ( this.original == null ) { wrap( this.path ); } diff --git a/uberfire-api/src/main/java/org/uberfire/mvp/Command.java b/uberfire-api/src/main/java/org/uberfire/mvp/Command.java index 3a1e7b91f7..50f5c3d11e 100644 --- a/uberfire-api/src/main/java/org/uberfire/mvp/Command.java +++ b/uberfire-api/src/main/java/org/uberfire/mvp/Command.java @@ -15,11 +15,14 @@ */ 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(); diff --git a/uberfire-api/src/main/java/org/uberfire/mvp/PlaceRequest.java b/uberfire-api/src/main/java/org/uberfire/mvp/PlaceRequest.java index 276b11ad1b..ac89af190b 100644 --- a/uberfire-api/src/main/java/org/uberfire/mvp/PlaceRequest.java +++ b/uberfire-api/src/main/java/org/uberfire/mvp/PlaceRequest.java @@ -19,8 +19,11 @@ import java.util.Map; import java.util.Set; +import org.uberfire.backend.vfs.Path; import org.uberfire.mvp.impl.DefaultPlaceRequest; +import jsinterop.annotations.JsType; + /** * 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. @@ -28,6 +31,7 @@ * 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" ); @@ -55,5 +59,20 @@ PlaceRequest addParameter( final String name, * Indicates whether or not the Workbench framework should add a browser history item when navigating to this place. */ boolean isUpdateLocationBarAllowed(); - + + /** + * 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(); + } + } diff --git a/uberfire-api/src/main/java/org/uberfire/mvp/impl/DefaultPlaceRequest.java b/uberfire-api/src/main/java/org/uberfire/mvp/impl/DefaultPlaceRequest.java index 21eb0a8cdd..88da97f40e 100644 --- a/uberfire-api/src/main/java/org/uberfire/mvp/impl/DefaultPlaceRequest.java +++ b/uberfire-api/src/main/java/org/uberfire/mvp/impl/DefaultPlaceRequest.java @@ -155,7 +155,7 @@ public String getFullIdentifier() { StringBuilder fullIdentifier = new StringBuilder(); fullIdentifier.append( this.getIdentifier() ); - if ( this.getParameterNames().size() > 0 ) { + if ( !this.getParameterNames().isEmpty() ) { fullIdentifier.append( "?" ); } for ( String name : this.getParameterNames() ) { diff --git a/uberfire-api/src/main/java/org/uberfire/mvp/impl/ExternalPathPlaceRequest.java b/uberfire-api/src/main/java/org/uberfire/mvp/impl/ExternalPathPlaceRequest.java new file mode 100644 index 0000000000..6e0f09ba88 --- /dev/null +++ b/uberfire-api/src/main/java/org/uberfire/mvp/impl/ExternalPathPlaceRequest.java @@ -0,0 +1,45 @@ +/* + * 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.uberfire.backend.vfs.Path; + +import jsinterop.annotations.JsIgnore; +import jsinterop.annotations.JsType; + +/** + * A {@link PathPlaceRequest} originating from an external script. + */ +@JsType +public class ExternalPathPlaceRequest extends DefaultPlaceRequest { + + private Path path; + + public ExternalPathPlaceRequest(Path path) { + this.path = path; + } + + @Override + public Path getPath() { + return path; + } + + @JsIgnore + public static ExternalPathPlaceRequest create(PathPlaceRequest request) { + return new ExternalPathPlaceRequest(request.getPath().getOriginal()); + } + +} diff --git a/uberfire-api/src/main/java/org/uberfire/mvp/impl/PathPlaceRequest.java b/uberfire-api/src/main/java/org/uberfire/mvp/impl/PathPlaceRequest.java index 5e430ae8a0..03189942f8 100644 --- a/uberfire-api/src/main/java/org/uberfire/mvp/impl/PathPlaceRequest.java +++ b/uberfire-api/src/main/java/org/uberfire/mvp/impl/PathPlaceRequest.java @@ -65,6 +65,7 @@ public PathPlaceRequest( final Path path, this.parameters.putAll( parameters ); } + @Override public ObservablePath getPath() { return path; } diff --git a/uberfire-api/src/main/java/org/uberfire/plugin/PluginUtil.java b/uberfire-api/src/main/java/org/uberfire/plugin/PluginUtil.java new file mode 100644 index 0000000000..0d51ff753a --- /dev/null +++ b/uberfire-api/src/main/java/org/uberfire/plugin/PluginUtil.java @@ -0,0 +1,97 @@ +/* + * 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.uberfire.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; + } +} diff --git a/uberfire-api/src/main/java/org/uberfire/security/Resource.java b/uberfire-api/src/main/java/org/uberfire/security/Resource.java index 4900a24cd8..32e5a00e1b 100644 --- a/uberfire-api/src/main/java/org/uberfire/security/Resource.java +++ b/uberfire-api/src/main/java/org/uberfire/security/Resource.java @@ -19,14 +19,18 @@ 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()}). + * An identifier that is unique among all the resources of the same type + * (see {@link Resource#getResourceType()}). */ String getIdentifier(); @@ -40,12 +44,28 @@ default ResourceType getResourceType() { /** * 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.

+ *

+ * 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 or null if this resource has no dependencies. + * @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 ); + } } diff --git a/uberfire-api/src/main/java/org/uberfire/security/ResourceAction.java b/uberfire-api/src/main/java/org/uberfire/security/ResourceAction.java index 3cc33e891e..80a05a6b9c 100644 --- a/uberfire-api/src/main/java/org/uberfire/security/ResourceAction.java +++ b/uberfire-api/src/main/java/org/uberfire/security/ResourceAction.java @@ -16,6 +16,8 @@ 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. @@ -23,6 +25,7 @@ *

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 { /** diff --git a/uberfire-api/src/main/java/org/uberfire/security/ResourceType.java b/uberfire-api/src/main/java/org/uberfire/security/ResourceType.java index 40e91d3f55..d48aa1515e 100644 --- a/uberfire-api/src/main/java/org/uberfire/security/ResourceType.java +++ b/uberfire-api/src/main/java/org/uberfire/security/ResourceType.java @@ -16,9 +16,12 @@ package org.uberfire.security; +import jsinterop.annotations.JsType; + /** * Type interface for {@link Resource} instances */ +@JsType public interface ResourceType { /** diff --git a/uberfire-api/src/main/java/org/uberfire/security/authz/ResourceActionRef.java b/uberfire-api/src/main/java/org/uberfire/security/authz/ResourceActionRef.java index de7639bcb9..8793d4b3d0 100644 --- a/uberfire-api/src/main/java/org/uberfire/security/authz/ResourceActionRef.java +++ b/uberfire-api/src/main/java/org/uberfire/security/authz/ResourceActionRef.java @@ -21,28 +21,36 @@ import org.uberfire.security.ResourceRef; import org.uberfire.security.ResourceType; +import jsinterop.annotations.JsIgnore; +import jsinterop.annotations.JsType; + /** * 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; diff --git a/uberfire-api/src/main/java/org/uberfire/security/authz/RuntimeResource.java b/uberfire-api/src/main/java/org/uberfire/security/authz/RuntimeResource.java index d886402bd0..897267385e 100644 --- a/uberfire-api/src/main/java/org/uberfire/security/authz/RuntimeResource.java +++ b/uberfire-api/src/main/java/org/uberfire/security/authz/RuntimeResource.java @@ -18,6 +18,9 @@ import org.uberfire.security.Resource; +import jsinterop.annotations.JsType; + +@JsType public interface RuntimeResource extends Resource { } diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/events/PluginAddedEvent.java b/uberfire-api/src/main/java/org/uberfire/workbench/events/PluginAddedEvent.java new file mode 100644 index 0000000000..b01f335798 --- /dev/null +++ b/uberfire-api/src/main/java/org/uberfire/workbench/events/PluginAddedEvent.java @@ -0,0 +1,29 @@ +/* + * 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); + } + +} \ No newline at end of file diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/events/PluginEvent.java b/uberfire-api/src/main/java/org/uberfire/workbench/events/PluginEvent.java new file mode 100644 index 0000000000..e724509672 --- /dev/null +++ b/uberfire-api/src/main/java/org/uberfire/workbench/events/PluginEvent.java @@ -0,0 +1,29 @@ +/* + * 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; + } +} diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/events/PluginUpdatedEvent.java b/uberfire-api/src/main/java/org/uberfire/workbench/events/PluginUpdatedEvent.java new file mode 100644 index 0000000000..d0d387e7d1 --- /dev/null +++ b/uberfire-api/src/main/java/org/uberfire/workbench/events/PluginUpdatedEvent.java @@ -0,0 +1,29 @@ +/* + * 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); + } + +} \ No newline at end of file diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/events/PluginsReloadedEvent.java b/uberfire-api/src/main/java/org/uberfire/workbench/events/PluginsReloadedEvent.java new file mode 100644 index 0000000000..da983589c7 --- /dev/null +++ b/uberfire-api/src/main/java/org/uberfire/workbench/events/PluginsReloadedEvent.java @@ -0,0 +1,24 @@ +/* + * 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 PluginsReloadedEvent { + +} \ No newline at end of file diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/ActivityResourceType.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/ActivityResourceType.java index 4202bfaa16..1949eb7cda 100644 --- a/uberfire-api/src/main/java/org/uberfire/workbench/model/ActivityResourceType.java +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/ActivityResourceType.java @@ -17,10 +17,13 @@ import org.uberfire.security.ResourceType; +import jsinterop.annotations.JsType; + /** * 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, diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/CompassPosition.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/CompassPosition.java index d1db5acdf1..0a4ea89f6b 100644 --- a/uberfire-api/src/main/java/org/uberfire/workbench/model/CompassPosition.java +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/CompassPosition.java @@ -17,10 +17,13 @@ import org.jboss.errai.common.client.api.annotations.Portable; +import jsinterop.annotations.JsType; + /** * Positions to which a WorkbenchPanel can be added to the Workbench */ @Portable +@JsType public enum CompassPosition implements Position { NONE, //Don't add anywhere diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/ContextDefinition.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/ContextDefinition.java index 242e4ac9c9..f84d066834 100644 --- a/uberfire-api/src/main/java/org/uberfire/workbench/model/ContextDefinition.java +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/ContextDefinition.java @@ -17,9 +17,12 @@ import org.uberfire.mvp.PlaceRequest; +import jsinterop.annotations.JsType; + /** * A Part in the Workbench. Parts are added to Panels. */ +@JsType public interface ContextDefinition { /** diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/ContextDisplayMode.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/ContextDisplayMode.java index 8349ff0f8f..08da83f300 100644 --- a/uberfire-api/src/main/java/org/uberfire/workbench/model/ContextDisplayMode.java +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/ContextDisplayMode.java @@ -18,6 +18,9 @@ import org.jboss.errai.common.client.api.annotations.Portable; +import jsinterop.annotations.JsType; + +@JsType @Portable public enum ContextDisplayMode { SHOW, diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/PanelDefinition.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/PanelDefinition.java index 4932906ec6..11c4b3ffe2 100644 --- a/uberfire-api/src/main/java/org/uberfire/workbench/model/PanelDefinition.java +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/PanelDefinition.java @@ -21,12 +21,17 @@ import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.DefaultPlaceRequest; +import jsinterop.annotations.JsIgnore; +import jsinterop.annotations.JsMethod; +import jsinterop.annotations.JsType; + /** * 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 { /** @@ -76,6 +81,7 @@ public interface PanelDefinition { * 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 ); /** @@ -118,6 +124,7 @@ public void insertChild( final Position position, * @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 ); @@ -180,52 +187,118 @@ public void appendChild( * Get the height of the Panel in pixels * @return The height, or null if not set */ + @JsIgnore public Integer getHeight(); + /** + * 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 ); + /** + * 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 width of this panel in pixels. * * @return The width, or null if not set. */ + @JsIgnore public Integer getWidth(); + + /** + * 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 ); + + /** + * 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 minimum height of this panel in pixels. * * @return The minimum height, or null if not set. */ + @JsIgnore public Integer getMinHeight(); + + /** + * 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; + } /** * 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 the Panel in pixels * @return The minimum width, or null if not set */ + @JsIgnore public Integer getMinWidth(); + + /** + * 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; + } /** * Set the minimum width of the Panel in pixels * @param minWidth The width, or null if not set */ + @JsIgnore public void setMinWidth( Integer minWidth ); /** @@ -261,5 +334,12 @@ public void appendChild( 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(); + } } diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/PartDefinition.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/PartDefinition.java index cccc9ea153..7a757b21cd 100644 --- a/uberfire-api/src/main/java/org/uberfire/workbench/model/PartDefinition.java +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/PartDefinition.java @@ -17,6 +17,8 @@ import org.uberfire.mvp.PlaceRequest; +import jsinterop.annotations.JsType; + /** * 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 @@ -24,6 +26,7 @@ * 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(); @@ -39,4 +42,11 @@ public interface PartDefinition { 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(); + } } diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/PerspectiveDefinition.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/PerspectiveDefinition.java index c2cc880787..b3fa6344b2 100644 --- a/uberfire-api/src/main/java/org/uberfire/workbench/model/PerspectiveDefinition.java +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/PerspectiveDefinition.java @@ -15,6 +15,8 @@ */ 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 @@ -24,6 +26,7 @@ *

* Implementations of this interface must be marked with Errai's {@code @Portable} annotation. */ +@JsType public interface PerspectiveDefinition { /** diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/Position.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/Position.java index 044a08d690..eeec3d4869 100644 --- a/uberfire-api/src/main/java/org/uberfire/workbench/model/Position.java +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/Position.java @@ -17,6 +17,8 @@ import org.jboss.errai.common.client.api.annotations.Portable; +import jsinterop.annotations.JsType; + /** * 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 @@ -24,5 +26,6 @@ *

* All implementations of this interface must be marked as {@link Portable}. */ +@JsType public interface Position { } diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/impl/PanelDefinitionImpl.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/impl/PanelDefinitionImpl.java index d86becff4b..caeda45812 100644 --- a/uberfire-api/src/main/java/org/uberfire/workbench/model/impl/PanelDefinitionImpl.java +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/impl/PanelDefinitionImpl.java @@ -15,8 +15,8 @@ */ package org.uberfire.workbench.model.impl; -import static org.uberfire.commons.validation.PortablePreconditions.*; -import static org.uberfire.workbench.model.ContextDisplayMode.*; +import static org.uberfire.commons.validation.PortablePreconditions.checkNotNull; +import static org.uberfire.workbench.model.ContextDisplayMode.SHOW; import java.util.ArrayList; import java.util.Collections; @@ -26,7 +26,6 @@ import java.util.Set; import org.jboss.errai.common.client.api.annotations.Portable; -import org.uberfire.debug.Debug; import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.workbench.model.CompassPosition; import org.uberfire.workbench.model.ContextDefinition; @@ -35,10 +34,14 @@ import org.uberfire.workbench.model.PartDefinition; import org.uberfire.workbench.model.Position; +import jsinterop.annotations.JsIgnore; +import jsinterop.annotations.JsType; + /** * Default implementation of PanelDefinition */ @Portable +@JsType public class PanelDefinitionImpl implements PanelDefinition { private Integer height = null; @@ -60,10 +63,12 @@ public class PanelDefinitionImpl implements PanelDefinition { 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; } @@ -116,11 +121,13 @@ public boolean removePart( PartDefinition part ) { } @Override + @JsIgnore public Set getParts() { return parts; } @Override + @JsIgnore public List getChildren() { return Collections.unmodifiableList( new ArrayList( children ) ); } @@ -237,11 +244,13 @@ public void setPanelType( String fqcn ) { } @Override + @JsIgnore public Integer getHeight() { return height; } @Override + @JsIgnore public void setHeight( Integer height ) { if ( height != null ) { this.height = height; @@ -249,11 +258,13 @@ public void setHeight( Integer height ) { } @Override + @JsIgnore public Integer getWidth() { return width; } @Override + @JsIgnore public void setWidth( Integer width ) { if ( width != null ) { this.width = width; @@ -261,21 +272,25 @@ public void setWidth( Integer 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; } diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/impl/PartDefinitionImpl.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/impl/PartDefinitionImpl.java index f4e9c666a9..00f7e2f405 100644 --- a/uberfire-api/src/main/java/org/uberfire/workbench/model/impl/PartDefinitionImpl.java +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/impl/PartDefinitionImpl.java @@ -128,4 +128,4 @@ public String toString() { return "PartDefinitionImpl [place=" + place + "]"; } -} +} \ No newline at end of file diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/EnabledStateChangeListener.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/EnabledStateChangeListener.java index ba82c1fa63..7103677055 100644 --- a/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/EnabledStateChangeListener.java +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/EnabledStateChangeListener.java @@ -15,9 +15,12 @@ */ package org.uberfire.workbench.model.menu; +import jsinterop.annotations.JsType; + /** * A Listener for changes in a Widget's enabled state */ +@JsType public interface EnabledStateChangeListener { /** diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/HasEnabledStateChangeListeners.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/HasEnabledStateChangeListeners.java index d382cd79d9..9b7e5dd1ea 100644 --- a/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/HasEnabledStateChangeListeners.java +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/HasEnabledStateChangeListeners.java @@ -16,9 +16,12 @@ package org.uberfire.workbench.model.menu; +import jsinterop.annotations.JsType; + /** * A source of EnabledStateChange actions. */ +@JsType public interface HasEnabledStateChangeListeners { /** diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuCustom.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuCustom.java index 26b4ad1da9..10e2ff9001 100644 --- a/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuCustom.java +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuCustom.java @@ -16,11 +16,14 @@ 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 { diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuGroup.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuGroup.java index a5028835f8..8d74b82049 100644 --- a/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuGroup.java +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuGroup.java @@ -18,9 +18,12 @@ import java.util.List; +import jsinterop.annotations.JsType; + /** * A menu item that has child items nested under it. */ +@JsType public interface MenuGroup extends MenuItem { diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuItem.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuItem.java index 306de8661e..0b98bbd4f5 100644 --- a/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuItem.java +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuItem.java @@ -21,13 +21,15 @@ import org.uberfire.security.authz.ResourceActionRef; import org.uberfire.security.authz.RuntimeFeatureResource; +import jsinterop.annotations.JsIgnore; +import jsinterop.annotations.JsType; + /** * 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. */ -public interface MenuItem - extends RuntimeFeatureResource, - HasEnabledStateChangeListeners { +@JsType +public interface MenuItem extends RuntimeFeatureResource, HasEnabledStateChangeListeners { boolean isEnabled(); @@ -42,9 +44,13 @@ public interface MenuItem int getOrder(); /** - * Get the list of {@link ResourceActionRef} actions this menu item is restricted to. + * 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.

+ *

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

*/ default List getResourceActions() { return Collections.emptyList(); @@ -53,14 +59,18 @@ default List getResourceActions() { /** * 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.

+ *

+ * 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. + * Causes the given {@link MenuVisitor} to visit this menu item and its + * children. */ void accept( MenuVisitor visitor ); } diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuItemCommand.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuItemCommand.java index 4526cbc216..4007fe0ed4 100644 --- a/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuItemCommand.java +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuItemCommand.java @@ -17,9 +17,12 @@ import org.uberfire.mvp.Command; +import jsinterop.annotations.JsType; + /** * A menu item that invokes a particular {@link Command} when it is clicked. */ +@JsType public interface MenuItemCommand extends MenuItem { diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuItemPerspective.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuItemPerspective.java index a19c8515bf..a10f05d968 100644 --- a/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuItemPerspective.java +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuItemPerspective.java @@ -18,9 +18,12 @@ import org.uberfire.mvp.PlaceRequest; +import jsinterop.annotations.JsType; + /** * 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(); diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuItemPlain.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuItemPlain.java index 71fbd639e3..1b51809ea6 100644 --- a/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuItemPlain.java +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuItemPlain.java @@ -18,9 +18,12 @@ import org.uberfire.mvp.Command; +import jsinterop.annotations.JsType; + /** * A menu item that has no children and no specific {@link Command} associated with it. */ +@JsType public interface MenuItemPlain extends MenuItem { } diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuPosition.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuPosition.java index 6ab50de384..0ab99fe453 100644 --- a/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuPosition.java +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuPosition.java @@ -16,9 +16,12 @@ package org.uberfire.workbench.model.menu; +import jsinterop.annotations.JsType; + /** * Defines the menu position on the navbar. */ +@JsType public enum MenuPosition { LEFT, RIGHT } diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuVisitor.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuVisitor.java index bc4afdae71..e16172a1dd 100644 --- a/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuVisitor.java +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuVisitor.java @@ -16,12 +16,15 @@ 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 { /** @@ -54,6 +57,7 @@ public interface MenuVisitor { * descendants. In particular, there will be no corresponding {@link #visitLeave(MenuGroup)} call for this * node. */ + @JsMethod(name="visitEnterGroup") boolean visitEnter( MenuGroup menuGroup ); /** @@ -63,6 +67,7 @@ public interface MenuVisitor { * * @param menuGroup the menu group to leave. */ + @JsMethod(name="visitLeaveGroup") void visitLeave( MenuGroup menuGroup ); /** @@ -77,6 +82,7 @@ public interface MenuVisitor { * * @param menuItemCommand the command menu item to visit. */ + @JsMethod(name="visitCommand") void visit( MenuItemCommand menuItemCommand ); /** @@ -84,6 +90,7 @@ public interface MenuVisitor { * * @param menuItemPerspective the command menu item to visit. */ + @JsMethod(name="visitPerspective") void visit( MenuItemPerspective menuItemPerspective ); /** @@ -91,5 +98,6 @@ public interface MenuVisitor { * * @param menuCustom the custom (application provides the widget) menu item to visit. */ + @JsMethod(name="visitCustom") void visit( MenuCustom menuCustom ); } diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/Menus.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/Menus.java index 937fdd35fb..bc9da8a3e4 100644 --- a/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/Menus.java +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/Menus.java @@ -18,9 +18,12 @@ import java.util.List; import java.util.Map; +import jsinterop.annotations.JsType; + /** * Menus that includes permission */ +@JsType public interface Menus { /** diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/impl/BaseMenuCustom.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/impl/BaseMenuCustom.java index 6e5c681c21..768f5791d5 100644 --- a/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/impl/BaseMenuCustom.java +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/impl/BaseMenuCustom.java @@ -16,12 +16,6 @@ package org.uberfire.workbench.model.menu.impl; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.uberfire.security.Resource; -import org.uberfire.security.ResourceType; import org.uberfire.workbench.model.menu.EnabledStateChangeListener; import org.uberfire.workbench.model.menu.MenuCustom; import org.uberfire.workbench.model.menu.MenuPosition; @@ -115,4 +109,4 @@ public void accept( final MenuVisitor visitor ) { public void addEnabledStateChangeListener( final EnabledStateChangeListener listener ) { } -} +} \ No newline at end of file diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/impl/DefaultMenuGroup.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/impl/DefaultMenuGroup.java new file mode 100644 index 0000000000..eb309f4b16 --- /dev/null +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/impl/DefaultMenuGroup.java @@ -0,0 +1,151 @@ +/* + * 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 static org.uberfire.plugin.PluginUtil.*; + +import java.util.ArrayList; +import java.util.List; + +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 jsinterop.annotations.JsIgnore; +import jsinterop.annotations.JsType; + +@JsType +public class DefaultMenuGroup implements MenuGroup { + + private final List enabledStateChangeListeners = new ArrayList(); + private boolean isEnabled = true; + + private final List menuItems; + private final String contributionPoint; + private final String caption; + private final MenuPosition position; + private final int order; + 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; + } +} \ No newline at end of file diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/impl/DefaultMenus.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/impl/DefaultMenus.java new file mode 100644 index 0000000000..9e3023900e --- /dev/null +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/impl/DefaultMenus.java @@ -0,0 +1,77 @@ +/* + * 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 org.uberfire.workbench.model.menu.MenuItem; +import org.uberfire.workbench.model.menu.MenuVisitor; +import org.uberfire.workbench.model.menu.Menus; + +import jsinterop.annotations.JsIgnore; +import jsinterop.annotations.JsType; + +@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; + } +} \ No newline at end of file diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/impl/MenuBuilderImpl.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/impl/MenuBuilderImpl.java index 0110446ec6..c42fab2ebb 100644 --- a/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/impl/MenuBuilderImpl.java +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/menu/impl/MenuBuilderImpl.java @@ -16,6 +16,10 @@ package org.uberfire.workbench.model.menu.impl; +import static java.util.Collections.unmodifiableList; +import static org.uberfire.commons.validation.PortablePreconditions.checkNotEmpty; +import static org.uberfire.commons.validation.PortablePreconditions.checkNotNull; + import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -43,8 +47,7 @@ import org.uberfire.workbench.model.menu.MenuVisitor; import org.uberfire.workbench.model.menu.Menus; -import static java.util.Collections.*; -import static org.uberfire.commons.validation.PortablePreconditions.*; +import jsinterop.annotations.JsType; /** * @@ -58,6 +61,7 @@ public final class MenuBuilderImpl MenuFactory.TerminalMenu, MenuFactory.TerminalCustomMenu { + public enum MenuType { TOP_LEVEL, CONTRIBUTED, REGULAR, GROUP, CUSTOM } @@ -99,91 +103,8 @@ public MenuItem build() { menuItems.add( current.build() ); } } - return new MenuGroup() { - private final List enabledStateChangeListeners = new ArrayList(); - private boolean isEnabled = true; - - @Override - public List getItems() { - return menuItems; - } - - @Override - public String getIdentifier() { - 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() { - 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 ); - } - - @Override - public void addEnabledStateChangeListener( final EnabledStateChangeListener listener ) { - enabledStateChangeListeners.add( listener ); - } - @Override - public void accept( MenuVisitor visitor ) { - if ( visitor.visitEnter( this ) ) { - for ( MenuItem child : getItems() ) { - child.accept( visitor ); - } - visitor.visitLeave( this ); - } - } - - private void notifyListeners( final boolean enabled ) { - for ( final EnabledStateChangeListener listener : enabledStateChangeListeners ) { - listener.enabledStateChanged( enabled ); - } - } - }; + return new DefaultMenuGroup(menuItems, resourceActionRefs, permissionNames, contributionPoint, caption, position, order); } else if ( command != null ) { return new MenuItemCommand() { @@ -654,37 +575,8 @@ public MenuBuilderImpl orderAll( final int order ) { @Override public Menus build() { - context.clear(); - return new Menus() { - @Override - public List getItems() { - return unmodifiableList( menuItems ); - } - - @Override - public void accept( MenuVisitor visitor ) { - if ( visitor.visitEnter( this ) ) { - for ( MenuItem item : menuItems ) { - item.accept( visitor ); - } - visitor.visitLeave( this ); - } - } - - @Override - public Map getItemsMap() { - return new HashMap() {{ - for ( final MenuItem menuItem : menuItems ) { - put( menuItem, menuItem ); - } - }}; - } - - public int getOrder() { - return order; - } - }; + return new DefaultMenus(menuItems, order); } } diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/toolbar/ToolBar.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/toolbar/ToolBar.java index 3bf5868275..3fdaf23df1 100644 --- a/uberfire-api/src/main/java/org/uberfire/workbench/model/toolbar/ToolBar.java +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/toolbar/ToolBar.java @@ -19,9 +19,12 @@ import org.uberfire.security.authz.RuntimeFeatureResource; +import jsinterop.annotations.JsType; + /** * Meta-data for a Workbench Tool Bar including permissions */ +@JsType public interface ToolBar extends RuntimeFeatureResource { diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/toolbar/ToolBarIcon.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/toolbar/ToolBarIcon.java index 4bc6c5fed2..1629ff483c 100644 --- a/uberfire-api/src/main/java/org/uberfire/workbench/model/toolbar/ToolBarIcon.java +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/toolbar/ToolBarIcon.java @@ -16,9 +16,12 @@ package org.uberfire.workbench.model.toolbar; +import jsinterop.annotations.JsType; + /** * */ +@JsType public interface ToolBarIcon { } diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/toolbar/ToolBarItem.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/toolbar/ToolBarItem.java index 41507a0053..d01a969fc9 100644 --- a/uberfire-api/src/main/java/org/uberfire/workbench/model/toolbar/ToolBarItem.java +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/toolbar/ToolBarItem.java @@ -17,13 +17,15 @@ import org.uberfire.mvp.Command; import org.uberfire.security.authz.RuntimeFeatureResource; -import org.uberfire.security.authz.RuntimeResource; + +import jsinterop.annotations.JsType; /** * 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 { diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/model/toolbar/impl/DefaultToolBar.java b/uberfire-api/src/main/java/org/uberfire/workbench/model/toolbar/impl/DefaultToolBar.java index 5e413a5f7e..bea5237438 100644 --- a/uberfire-api/src/main/java/org/uberfire/workbench/model/toolbar/impl/DefaultToolBar.java +++ b/uberfire-api/src/main/java/org/uberfire/workbench/model/toolbar/impl/DefaultToolBar.java @@ -15,17 +15,15 @@ */ package org.uberfire.workbench.model.toolbar.impl; +import static org.uberfire.commons.validation.PortablePreconditions.checkNotEmpty; +import static org.uberfire.commons.validation.PortablePreconditions.checkNotNull; + import java.util.ArrayList; -import java.util.Collection; import java.util.List; -import org.uberfire.security.Resource; -import org.uberfire.security.ResourceType; import org.uberfire.workbench.model.toolbar.ToolBar; import org.uberfire.workbench.model.toolbar.ToolBarItem; -import static org.uberfire.commons.validation.PortablePreconditions.*; - /** * Default implementation of ToolBar */ @@ -60,4 +58,5 @@ public void addItem( final ToolBarItem item ) { public List getItems() { return this.items; } + } diff --git a/uberfire-api/src/main/java/org/uberfire/workbench/type/ResourceTypeDefinition.java b/uberfire-api/src/main/java/org/uberfire/workbench/type/ResourceTypeDefinition.java index cf6fba1039..78f3ba7d00 100644 --- a/uberfire-api/src/main/java/org/uberfire/workbench/type/ResourceTypeDefinition.java +++ b/uberfire-api/src/main/java/org/uberfire/workbench/type/ResourceTypeDefinition.java @@ -18,9 +18,12 @@ import org.uberfire.backend.vfs.Path; +import jsinterop.annotations.JsType; + /** * Definition of a Resource Type */ +@JsType public interface ResourceTypeDefinition { /** diff --git a/uberfire-api/src/main/resources/org/uberfire/UberfireAPI.gwt.xml b/uberfire-api/src/main/resources/org/uberfire/UberfireAPI.gwt.xml index 66e86bcf1f..78f9edb0ec 100644 --- a/uberfire-api/src/main/resources/org/uberfire/UberfireAPI.gwt.xml +++ b/uberfire-api/src/main/resources/org/uberfire/UberfireAPI.gwt.xml @@ -27,6 +27,7 @@ + diff --git a/uberfire-api/src/test/java/org/uberfire/workbench/model/impl/PanelDefinitionImplTest.java b/uberfire-api/src/test/java/org/uberfire/workbench/model/impl/PanelDefinitionImplTest.java index 85fccf6644..55ebabd0ea 100644 --- a/uberfire-api/src/test/java/org/uberfire/workbench/model/impl/PanelDefinitionImplTest.java +++ b/uberfire-api/src/test/java/org/uberfire/workbench/model/impl/PanelDefinitionImplTest.java @@ -66,15 +66,15 @@ public void addPartTwiceShouldWork() throws Exception { } @Test - public void widthShouldNotRevertToNullOnceSet() throws Exception { - assertNull( panelDefinition.getWidth() ); + public void widthShouldNotRevertOnceSet() throws Exception { + assertNull(panelDefinition.getWidth() ); panelDefinition.setWidth( 1234 ); - panelDefinition.setWidth( null ); + panelDefinition.setWidth( null); assertEquals( (Integer) 1234, panelDefinition.getWidth() ); } @Test - public void heightShouldNotRevertToNullOnceSet() throws Exception { + public void heightShouldNotRevertOnceSet() throws Exception { assertNull( panelDefinition.getHeight() ); panelDefinition.setHeight( 1234 ); panelDefinition.setHeight( null ); diff --git a/uberfire-backend/uberfire-backend-api/src/main/java/org/uberfire/backend/plugin/RuntimePluginsService.java b/uberfire-backend/uberfire-backend-api/src/main/java/org/uberfire/backend/plugin/RuntimePluginService.java similarity index 95% rename from uberfire-backend/uberfire-backend-api/src/main/java/org/uberfire/backend/plugin/RuntimePluginsService.java rename to uberfire-backend/uberfire-backend-api/src/main/java/org/uberfire/backend/plugin/RuntimePluginService.java index c1af460442..0182fec9be 100644 --- a/uberfire-backend/uberfire-backend-api/src/main/java/org/uberfire/backend/plugin/RuntimePluginsService.java +++ b/uberfire-backend/uberfire-backend-api/src/main/java/org/uberfire/backend/plugin/RuntimePluginService.java @@ -21,7 +21,7 @@ import org.jboss.errai.bus.server.annotations.Remote; @Remote -public interface RuntimePluginsService { +public interface RuntimePluginService { Collection listFramworksContent(); diff --git a/uberfire-backend/uberfire-backend-server/pom.xml b/uberfire-backend/uberfire-backend-server/pom.xml index d0cc666be4..50fc01a7ee 100644 --- a/uberfire-backend/uberfire-backend-server/pom.xml +++ b/uberfire-backend/uberfire-backend-server/pom.xml @@ -94,6 +94,11 @@ org.jboss.errai errai-bus + + + org.jboss.errai + errai-cdi-server + diff --git a/uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugin/GwtRuntimePluginLoader.java b/uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugin/GwtRuntimePluginLoader.java new file mode 100644 index 0000000000..8ca2f80860 --- /dev/null +++ b/uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugin/GwtRuntimePluginLoader.java @@ -0,0 +1,188 @@ +/* + * 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.plugin; + +import static org.apache.commons.lang3.StringUtils.substringAfterLast; + +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.Collection; +import java.util.Enumeration; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +import javax.enterprise.context.Dependent; +import javax.enterprise.event.Event; +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.workbench.events.PluginAddedEvent; +import org.uberfire.workbench.events.PluginUpdatedEvent; +import org.uberfire.workbench.events.PluginsReloadedEvent; + +/** + * Processes and activates deployed plugin jars. The corresponding .js files are + * registered with the {@link PluginRegistry} and are added to the host page's + * <head> element by Errai, so that all 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. + */ +@Dependent +public class GwtRuntimePluginLoader { + private static final Logger LOG = LoggerFactory.getLogger( GwtRuntimePluginLoader.class ); + + private PluginRegistry pluginRegistry; + + private Event pluginAddedEvent; + private Event pluginUpdatedEvent; + private Event pluginsReloadedEvent; + private String pluginDir; + private String pluginDeploymentUrlPath; + private String pluginDeploymentDir; + + @Inject + public GwtRuntimePluginLoader(final Event pluginAddedEvent, + final Event pluginUpdatedEvent, + final Event pluginsReloadedEvent) { + + this.pluginAddedEvent = pluginAddedEvent; + this.pluginUpdatedEvent = pluginUpdatedEvent; + this.pluginsReloadedEvent = pluginsReloadedEvent; + } + + /** + * Processes and loads the currently deployed plugins. + * + * @param contextRootDir + * the web application's context root directory, must not be + * null. + * @param pluginDir + * the plugin directory, must not be null. + * @param pluginDeploymentDir + * the directory to deploy plugin contents to, must not be null. + */ + public void init( final String contextRootDir, + final String pluginDir, + final String pluginDeploymentDir, + final PluginRegistry pluginRegistry ) throws IOException { + + this.pluginDeploymentUrlPath = substringAfterLast( pluginDeploymentDir, File.separator ); + this.pluginDeploymentDir = pluginDeploymentDir; + this.pluginDir = pluginDir; + this.pluginRegistry = pluginRegistry; + loadPlugins(); + } + + void loadPlugins() throws IOException { + pluginRegistry.removeAll(); + + final File pluginRoot = new File( pluginDir ); + if ( pluginRoot.exists() ) { + Collection deployedPlugins = FileUtils.listFiles( pluginRoot, + new String[]{"jar"}, + false ); + + deployedPlugins.forEach( p -> loadPlugin( Paths.get( p.getAbsolutePath() ), + false ) ); + } + } + + /** + * Clears the plugin registry and reloads all currently deployed plugins. + * Fires a {@link PluginsReloadedEvent} when done. + */ + public void reload() throws IOException { + loadPlugins(); + pluginsReloadedEvent.fire( new PluginsReloadedEvent() ); + } + + /** + * Unpacks the provided plugin (path pointing to a JAR file), searches for + * the corresponding JavaScript file and registers the plugin url with the + * {@link PluginRegistry}. + * + * @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 loadPlugin( Path path, boolean notifyClients ) { + final String pluginJs = processPluginJar( pluginDir + File.separator + path.toFile().getName() ); + + if ( pluginJs != null ) { + final String pluginDisplayName = pluginJs.replace( ".nocache.js", "" ); + + if ( !pluginRegistry.isRegistered( pluginJs ) ) { + final String url = pluginDeploymentUrlPath + "/" + pluginJs + "?nocache=" + System.currentTimeMillis(); + pluginRegistry.add( pluginJs, url ); + + if ( notifyClients ) { + pluginAddedEvent.fire( new PluginAddedEvent( pluginDisplayName ) ); + } + } else { + if ( notifyClients ) { + pluginUpdatedEvent.fire( new PluginUpdatedEvent( pluginDisplayName ) ); + } + } + } else { + LOG.warn( "Deployed plugin " + path.toFile().getName() + " does not contain a nocache.js file!" ); + } + } + + String processPluginJar( String jarFileName ) { + String pluginScriptFileName = null; + + 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 ( fileName.endsWith( "cache.js" ) ) { + final File f = new File( pluginDeploymentDir + File.separator + fileName ); + try ( InputStream is = jar.getInputStream( file ); + FileOutputStream fos = new FileOutputStream( f ) ) { + + while ( is.available() > 0 ) { + fos.write( is.read() ); + } + } + + if ( file.getName().endsWith( "nocache.js" ) ) { + pluginScriptFileName = fileName; + } + } + + } + } catch ( IOException e ) { + throw new RuntimeException( e ); + } + + return pluginScriptFileName; + } + +} \ No newline at end of file diff --git a/uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugin/GwtRuntimePluginManager.java b/uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugin/GwtRuntimePluginManager.java new file mode 100644 index 0000000000..cd5c7e1a7f --- /dev/null +++ b/uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugin/GwtRuntimePluginManager.java @@ -0,0 +1,147 @@ +/* + * 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.plugin; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +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.jboss.errai.cdi.server.scripts.ScriptRegistry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Manages GWT runtime plugins which involves monitoring the plugin directory + * (see {@link GwtRuntimePluginWatcher}), and loading the deployed plugins (see + * {@link GwtRuntimePluginLoader}). + */ +@Dependent +public class GwtRuntimePluginManager { + + private static final Logger LOG = LoggerFactory.getLogger( GwtRuntimePluginManager.class ); + static final String SCRIPT_REGISTRY_KEY = "UF"; + + private GwtRuntimePluginWatcher pluginWatcher; + private GwtRuntimePluginLoader pluginLoader; + private ExecutorService executor; + private ScriptRegistry scriptRegistry; + + @Inject + public GwtRuntimePluginManager( final GwtRuntimePluginWatcher pluginWatcher, + final GwtRuntimePluginLoader pluginLoader, + final ScriptRegistry scriptRegistry) { + + this.pluginWatcher = pluginWatcher; + this.pluginLoader = pluginLoader; + this.scriptRegistry = scriptRegistry; + this.executor = Executors.newSingleThreadExecutor(); + } + + @PreDestroy + void shutDown() { + pluginWatcher.stop(); + scriptRegistry.removeScripts( SCRIPT_REGISTRY_KEY ); + } + + /** + * Initializes the {@link GwtRuntimePluginLoader} and + * {@link GwtRuntimePluginWatcher} 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 { + pluginLoader.init( contextRootDir, + pluginDir, + findPluginDeploymentDir( contextRootDir ), + createPluginRegistry() ); + + pluginWatcher.start( pluginDir, + executor, + pluginLoader ); + } catch ( Exception e ) { + LOG.error( "Failed to initialize " + GwtRuntimePluginManager.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( contextRootDir ), + new String[]{"nocache.js"}, + true ); + if ( !gwtFiles.isEmpty() ) { + final File gwtFile = gwtFiles.iterator().next(); + return gwtFile.getParentFile().getCanonicalPath(); + } + return new File( contextRootDir ).getCanonicalPath(); + } + + private PluginRegistry createPluginRegistry() { + final Set availablePlugins = new HashSet(); + return new PluginRegistry() { + + @Override + public void add( String pluginName, String scriptUrl) { + availablePlugins.add( pluginName ); + scriptRegistry.addScript( SCRIPT_REGISTRY_KEY, scriptUrl ); + } + + @Override + public void remove( String pluginName, String scriptUrl ) { + availablePlugins.remove( pluginName ); + scriptRegistry.removeScript( 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 ); + } + }; + } + +} \ No newline at end of file diff --git a/uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugin/GwtRuntimePluginWatcher.java b/uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugin/GwtRuntimePluginWatcher.java new file mode 100644 index 0000000000..64849978ac --- /dev/null +++ b/uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugin/GwtRuntimePluginWatcher.java @@ -0,0 +1,136 @@ +/* + * 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.plugin; + +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; + +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; + +/** + * Monitors the plugin directory for changes and loads/removes plugins using the + * {@link GwtRuntimePluginLoader}. + */ +@Dependent +public class GwtRuntimePluginWatcher { + + private static final Logger LOG = LoggerFactory.getLogger( GwtRuntimePluginWatcher.class ); + + boolean active; + private ExecutorService executor; + + /** + * Starts the plugin 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 pluginLoader + * the plugin loader for registering and removing plugins + */ + void start( final String pluginDir, + final ExecutorService executor, + final GwtRuntimePluginLoader pluginLoader ) throws IOException { + + final Path pluginRootPath = Paths.get( pluginDir ); + if ( active || !Files.exists( pluginRootPath ) ) { + return; + } + + this.active = true; + this.executor = executor; + + final WatchService watchService = FileSystems.getDefault().newWatchService(); + pluginRootPath.register( watchService, + ENTRY_CREATE, + ENTRY_MODIFY, + ENTRY_DELETE ); + + startWatchService(watchService, pluginLoader); + } + + private void startWatchService(final WatchService watchService, final GwtRuntimePluginLoader pluginLoader) { + executor.submit( () -> { + while ( active ) { + try { + final WatchKey watchKey = watchService.poll( 5, TimeUnit.SECONDS ); + + if ( watchKey != null ) { + 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 ) { + if ( file.getFileName().toString().endsWith( ".jar" ) ) { + try { + pluginLoader.loadPlugin( file, true ); + } catch ( Exception e ) { + LOG.error( "Failed to process new plugin " + file.getFileName().toString(), e ); + } + } + } else if ( kind == ENTRY_DELETE ) { + try { + pluginLoader.reload(); + } catch ( Exception e ) { + LOG.error( "Failed to delete plugin " + file.getFileName().toString(), e ); + } + } + } + boolean valid = watchKey.reset(); + if ( !valid ) { + break; + } + } + } catch ( InterruptedException e ) { + active = false; + Thread.currentThread().interrupt(); + } + } + } ); + } + + void stop() { + active = false; + executor.shutdown(); + } + +} \ No newline at end of file diff --git a/uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugin/PluginRegistry.java b/uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugin/PluginRegistry.java new file mode 100644 index 0000000000..6c43d1f5e5 --- /dev/null +++ b/uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugin/PluginRegistry.java @@ -0,0 +1,60 @@ +/* + * 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.plugin; + +/** + * A simple registry to keep track of deployed plugins. + */ +public interface PluginRegistry { + + /** + * Registers the plugin with the given name and url. + * + * @param pluginName + * the name of the plugin, must not be null. + * @param scriptUrl + * the url of the plugin script, must not be null. + */ + void add( String pluginName, + String scriptUrl ); + + /** + * Removes the plugin from this registry. + * + * @param pluginName + * the name of the plugin, must not be null. + * @param scriptUrl + * the url of the plugin script, must not be null. + */ + void remove( String pluginName, + String scriptUrl ); + + /** + * Removes all plugins from this registry. + */ + void removeAll(); + + /** + * 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 ); + +} diff --git a/uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugin/PluginServletContextListener.java b/uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugin/PluginServletContextListener.java new file mode 100644 index 0000000000..a67ce4c019 --- /dev/null +++ b/uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugin/PluginServletContextListener.java @@ -0,0 +1,42 @@ +/* + * 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.plugin; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.servlet.annotation.WebListener; + +import org.uberfire.backend.plugin.RuntimePluginService; + +/** + * Initializes the {@link RuntimePluginService} when the web application starts + * up. + */ +@WebListener +public class PluginServletContextListener implements ServletContextListener { + + @Override + public void contextInitialized( ServletContextEvent sce ) { + RuntimePluginServiceImpl.getInstance().init( sce.getServletContext() ); + } + + @Override + public void contextDestroyed( ServletContextEvent sce ) { + + } + +} diff --git a/uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugin/RuntimePluginsServiceServerImpl.java b/uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugin/RuntimePluginServiceImpl.java similarity index 61% rename from uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugin/RuntimePluginsServiceServerImpl.java rename to uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugin/RuntimePluginServiceImpl.java index 69b308c4d2..e0d65ce1ea 100644 --- a/uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugin/RuntimePluginsServiceServerImpl.java +++ b/uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugin/RuntimePluginServiceImpl.java @@ -16,30 +16,73 @@ package org.uberfire.backend.server.plugin; +import java.io.File; import java.net.URI; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +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.jboss.errai.bus.server.api.RpcContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.uberfire.backend.plugin.RuntimePluginsService; +import org.uberfire.backend.plugin.RuntimePluginService; +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; +/** + * Provides an Errai RPC endpoint to serve JavaScript runtime plugins (authored + * in plain JS) 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 GwtRuntimePluginManager} which + * is responsible for loading plugins authored in GWT/Errai/UberFire. These + * plugin scripts are injected in the host page by Errai once they are + * registered with Errai's script registry. They 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 -public class RuntimePluginsServiceServerImpl implements RuntimePluginsService { - - private static final Logger LOGGER = LoggerFactory.getLogger(RuntimePluginsServiceServerImpl.class); - +@Startup(StartupType.BOOTSTRAP) +public class RuntimePluginServiceImpl implements RuntimePluginService { + + private static final Logger LOGGER = LoggerFactory.getLogger(RuntimePluginServiceImpl.class); + + private static RuntimePluginServiceImpl instance; + + @Inject + private GwtRuntimePluginManager gwtRuntimePluginManager; + + @PostConstruct + private void startUp() { + instance = this; + } + + public static RuntimePluginServiceImpl getInstance() { + if ( instance == null ) { + throw new IllegalStateException( RuntimePluginService.class.getName() + " was not initialized on startup" ); + } + return instance; + } + + public void init( final ServletContext servletContext ) { + final String contextRootDir = getRealPath( servletContext, File.separator ); + final String pluginDir = getRealPath( servletContext, "plugins" ); + if ( contextRootDir != null && pluginDir != null ) { + gwtRuntimePluginManager.init( contextRootDir, pluginDir ); + } + } + @Override public Collection listFramworksContent() { return directoryContent( "frameworks", "*.js" ); @@ -95,8 +138,11 @@ private Collection directoryContent( final String directory, } private String getRealPath( final String path ) { - ServletContext servletContext = RpcContext.getHttpSession().getServletContext(); - String realPath = servletContext.getRealPath( path ); + return getRealPath(RpcContext.getServletRequest().getServletContext(), path); + } + + private String getRealPath( final ServletContext servletContext, final String path ) { + final String realPath = servletContext.getRealPath( path ); if (realPath == null) { return null; } diff --git a/uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/security/FileSystemResourceAdaptor.java b/uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/security/FileSystemResourceAdaptor.java index 4e93df2388..b38b5c8284 100644 --- a/uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/security/FileSystemResourceAdaptor.java +++ b/uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/security/FileSystemResourceAdaptor.java @@ -16,12 +16,9 @@ package org.uberfire.backend.server.security; -import java.util.List; - import org.uberfire.backend.authz.FileSystemResourceType; import org.uberfire.java.nio.base.FileSystemId; import org.uberfire.java.nio.file.FileSystem; -import org.uberfire.security.Resource; import org.uberfire.security.ResourceType; import org.uberfire.security.authz.RuntimeContentResource; @@ -54,5 +51,6 @@ public String getIdentifier() { @Override public ResourceType getResourceType() { return RESOURCE_TYPE; - } + } + } diff --git a/uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/plugin/AbstractGwtRuntimePluginTest.java b/uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/plugin/AbstractGwtRuntimePluginTest.java new file mode 100644 index 0000000000..1e105d3a90 --- /dev/null +++ b/uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/plugin/AbstractGwtRuntimePluginTest.java @@ -0,0 +1,42 @@ +/* + * 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.plugin; + +import java.io.File; + +import org.junit.Before; +import static org.junit.Assert.fail; + +public abstract class AbstractGwtRuntimePluginTest { + + String contextRootDir; + String pluginDir; + 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."); + } + } +} diff --git a/uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/plugin/GwtRuntimePluginLoaderTest.java b/uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/plugin/GwtRuntimePluginLoaderTest.java new file mode 100644 index 0000000000..ab280a4b24 --- /dev/null +++ b/uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/plugin/GwtRuntimePluginLoaderTest.java @@ -0,0 +1,129 @@ +/* + * 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.plugin; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doReturn; +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 java.nio.file.Paths; + +import javax.enterprise.event.Event; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.uberfire.workbench.events.PluginAddedEvent; +import org.uberfire.workbench.events.PluginUpdatedEvent; +import org.uberfire.workbench.events.PluginsReloadedEvent; + +@RunWith(MockitoJUnitRunner.class) +public class GwtRuntimePluginLoaderTest extends AbstractGwtRuntimePluginTest { + + private GwtRuntimePluginLoader pluginLoader; + + @Mock + private Event pluginAddedEvent; + + @Mock + private Event pluginUpdatedEvent; + + @Mock + private Event pluginsReloadedEvent; + + @Mock + private PluginRegistry pluginRegistry; + + @Before + public void setup() { + super.setup(); + + pluginLoader = spy( new GwtRuntimePluginLoader( pluginAddedEvent, + pluginUpdatedEvent, + pluginsReloadedEvent) ); + + } + + @Test + public void initLoadsDeployedPlugins() throws Exception { + pluginLoader.init( contextRootDir, pluginDir, pluginDeploymentDir, pluginRegistry ); + verify(pluginLoader).loadPlugins(); + } + + @Test + public void reloadClearsPluginRegistry() throws Exception { + pluginLoader.init( contextRootDir, pluginDir, pluginDeploymentDir, pluginRegistry ); + pluginLoader.reload(); + verify(pluginRegistry, times(2)).removeAll(); + } + + @Test + public void reloadFiresPluginsReloadedEvent() throws Exception { + pluginLoader.init( contextRootDir, pluginDir, pluginDeploymentDir, pluginRegistry ); + pluginLoader.reload(); + + verify(pluginsReloadedEvent).fire( any(PluginsReloadedEvent.class) ); + } + + @Test + public void loadPluginRegistersScript() throws Exception { + pluginLoader.init( contextRootDir, pluginDir, pluginDeploymentDir, pluginRegistry ); + doReturn("test.nocache.js").when(pluginLoader).processPluginJar( any(String.class) ); + + final ArgumentCaptor url = ArgumentCaptor.forClass(String.class); + final ArgumentCaptor name = ArgumentCaptor.forClass(String.class); + pluginLoader.loadPlugin( Paths.get( "test" ), false ); + verify(pluginRegistry).isRegistered("test.nocache.js"); + verify(pluginRegistry).add( name.capture(), url.capture() ); + + assertEquals("test.nocache.js", name.getValue()); + assertNotNull(url.getValue()); + assertTrue(url.getValue().startsWith( "test-app/test.nocache.js?nocache=" )); + } + + @Test + public void loadPluginFiresPluginAddedEvent() throws Exception { + pluginLoader.init( contextRootDir, pluginDir, pluginDeploymentDir, pluginRegistry ); + doReturn("test.nocache.js").when(pluginLoader).processPluginJar( any(String.class) ); + + pluginLoader.loadPlugin( Paths.get( "test" ), true ); + verify(pluginRegistry).isRegistered("test.nocache.js"); + verify(pluginRegistry).add( any(String.class), any(String.class)); + verify(pluginAddedEvent).fire( any (PluginAddedEvent.class) ); + } + + @Test + public void loadPluginFiresPluginUpdatedEvent() throws Exception { + pluginLoader.init( contextRootDir, pluginDir, pluginDeploymentDir, pluginRegistry ); + doReturn("test.nocache.js").when(pluginLoader).processPluginJar( any(String.class) ); + when(pluginRegistry.isRegistered( "test.nocache.js" )).thenReturn( true ); + + pluginLoader.loadPlugin( Paths.get( "test" ), true ); + verify(pluginRegistry).isRegistered("test.nocache.js"); + verify(pluginUpdatedEvent).fire( any (PluginUpdatedEvent.class) ); + } + +} \ No newline at end of file diff --git a/uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/plugin/GwtRuntimePluginManagerTest.java b/uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/plugin/GwtRuntimePluginManagerTest.java new file mode 100644 index 0000000000..91039c1cd8 --- /dev/null +++ b/uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/plugin/GwtRuntimePluginManagerTest.java @@ -0,0 +1,114 @@ +/* + * 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.plugin; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import java.util.concurrent.ExecutorService; + +import org.jboss.errai.cdi.server.scripts.ScriptRegistry; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class GwtRuntimePluginManagerTest extends AbstractGwtRuntimePluginTest { + + @InjectMocks + private GwtRuntimePluginManager manager; + + @Mock + private GwtRuntimePluginWatcher pluginWatcher; + + @Mock + private GwtRuntimePluginLoader pluginLoader; + + @Mock + private ScriptRegistry scriptRegistry; + + @Test + public void initPluginLoader() throws Exception { + manager.init( contextRootDir, pluginDir ); + verify( pluginLoader, + times( 1 ) ).init( eq( contextRootDir ), + eq( pluginDir ), + eq( pluginDeploymentDir ), + any( PluginRegistry.class ) ); + } + + @Test + public void initStartsWatcher() throws Exception { + manager.init( contextRootDir, pluginDir ); + verify(pluginWatcher, times(1)).start(eq(pluginDir), any(ExecutorService.class), eq(pluginLoader)); + } + + @Test + public void shutdownStopsWatcher() throws Exception { + manager.shutDown( ); + verify(pluginWatcher, times(1)).stop(); + } + + @Test + public void shutDownRemovesScripts() throws Exception { + manager.shutDown( ); + verify(scriptRegistry, times(1)).removeScripts( "UF" ); + } + + @Test + public void findPluginDeploymentDir() throws Exception { + final String pluginDeploymentDir = manager.findPluginDeploymentDir( contextRootDir ); + assertEquals( this.pluginDeploymentDir, pluginDeploymentDir ); + } + + @Test + public void pluginRegistryUsesErraiScriptRegistry() throws Exception { + manager.init( contextRootDir, pluginDir ); + final ArgumentCaptor pluginRegistry = ArgumentCaptor.forClass(PluginRegistry.class); + + verify( pluginLoader, + times( 1 ) ).init( eq( contextRootDir ), + eq( pluginDir ), + eq( pluginDeploymentDir ), + pluginRegistry.capture() ); + + final PluginRegistry registry = pluginRegistry.getValue(); + registry.add( "test", "url"); + verify(scriptRegistry).addScript( GwtRuntimePluginManager.SCRIPT_REGISTRY_KEY, "url" ); + assertTrue(registry.isRegistered( "test" )); + + registry.remove( "test", "url" ); + verify(scriptRegistry).removeScript( GwtRuntimePluginManager.SCRIPT_REGISTRY_KEY, "url" ); + assertFalse(registry.isRegistered( "test" )); + + registry.add( "test", "url"); + assertTrue(registry.isRegistered( "test" )); + + registry.removeAll(); + verify(scriptRegistry).removeScripts( GwtRuntimePluginManager.SCRIPT_REGISTRY_KEY ); + assertFalse(registry.isRegistered( "test" )); + } + +} diff --git a/uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/plugin/GwtRuntimePluginWatcherTest.java b/uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/plugin/GwtRuntimePluginWatcherTest.java new file mode 100644 index 0000000000..bb63ed8a72 --- /dev/null +++ b/uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/plugin/GwtRuntimePluginWatcherTest.java @@ -0,0 +1,80 @@ +/* + * 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.plugin; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import java.util.concurrent.ExecutorService; + +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class GwtRuntimePluginWatcherTest extends AbstractGwtRuntimePluginTest { + + @InjectMocks + private GwtRuntimePluginWatcher pluginWatcher; + + @Mock + private GwtRuntimePluginLoader pluginLoader; + + @Mock + private ExecutorService executor; + + @After + public void tearDown() { + pluginWatcher.stop(); + } + + @Test + public void startSubmitsWatcherThread() throws Exception { + pluginWatcher.start( pluginDir, executor, pluginLoader ); + verify(executor, times(1)).submit( any (Runnable.class)); + } + + @Test + public void startDoesNotSubmitWatcherThreadIfPluginDirDoesNotExist() throws Exception { + pluginWatcher.start( pluginDir + "invalid", executor, pluginLoader ); + verify(executor, never()).submit( any (Runnable.class)); + } + + @Test + public void startOnlyOnce() throws Exception { + pluginWatcher.start( pluginDir, executor, pluginLoader ); + pluginWatcher.start( pluginDir, executor, pluginLoader ); + verify(executor, times(1)).submit( any (Runnable.class)); + } + + @Test + public void stopEndsWatcherThread() throws Exception { + pluginWatcher.start( pluginDir, executor, pluginLoader ); + assertTrue(pluginWatcher.active); + pluginWatcher.stop(); + assertFalse(pluginWatcher.active); + verify(executor, times(1)).shutdown( ); + } + +} diff --git a/uberfire-backend/uberfire-backend-server/src/test/resources/plugins/plugin.txt b/uberfire-backend/uberfire-backend-server/src/test/resources/plugins/plugin.txt new file mode 100644 index 0000000000..91497fd261 --- /dev/null +++ b/uberfire-backend/uberfire-backend-server/src/test/resources/plugins/plugin.txt @@ -0,0 +1 @@ +//do not delete. needed for testing. \ No newline at end of file diff --git a/uberfire-backend/uberfire-backend-server/src/test/resources/test-app/test-app.nocache.js b/uberfire-backend/uberfire-backend-server/src/test/resources/test-app/test-app.nocache.js new file mode 100644 index 0000000000..bcf51e3c5d --- /dev/null +++ b/uberfire-backend/uberfire-backend-server/src/test/resources/test-app/test-app.nocache.js @@ -0,0 +1 @@ +// do not delete. needed for testing. \ No newline at end of file diff --git a/uberfire-client-api/src/main/java/org/uberfire/client/annotations/WorkbenchEditor.java b/uberfire-client-api/src/main/java/org/uberfire/client/annotations/WorkbenchEditor.java index 88204fe1f0..64e9e39a50 100644 --- a/uberfire-client-api/src/main/java/org/uberfire/client/annotations/WorkbenchEditor.java +++ b/uberfire-client-api/src/main/java/org/uberfire/client/annotations/WorkbenchEditor.java @@ -106,5 +106,13 @@ enum LockingStrategy { EDITOR_PROVIDED, // No locks are acquired, editor implementations need their own conflict resolution logic (if desired). FRAMEWORK_PESSIMISTIC // Locks are acquired allowing edits by only one user at a time } + + /** + * Indicates that this screen can be discovered and loaded at runtime. + * This is useful when building plugins or extensions where the screen + * is part of an external script loaded at runtime, as opposed to being + * statically compiled into the main application. + */ + boolean isDynamic() default false; } diff --git a/uberfire-client-api/src/main/java/org/uberfire/client/annotations/WorkbenchPerspective.java b/uberfire-client-api/src/main/java/org/uberfire/client/annotations/WorkbenchPerspective.java index efa5e36a2b..17858fdef9 100644 --- a/uberfire-client-api/src/main/java/org/uberfire/client/annotations/WorkbenchPerspective.java +++ b/uberfire-client-api/src/main/java/org/uberfire/client/annotations/WorkbenchPerspective.java @@ -62,8 +62,9 @@ String identifier(); /** - * Indicates that this perspective should be opened by default when the workbench first starts. Exactly one - * perspective in the whole application should be marked as default. + * Indicates that this perspective should be opened by default when the + * workbench first starts. Exactly one perspective in the whole application + * should be marked as default. */ boolean isDefault() default false; @@ -78,4 +79,12 @@ * returned by the {@code @Perspective} method. */ boolean isTransient() default true; + + /** + * Indicates that this perspective can be discovered and loaded at runtime. + * This is useful when building plugins or extensions where the perspective + * is part of an external script loaded at runtime, as opposed to being + * statically compiled into the main application. + */ + boolean isDynamic() default false; } diff --git a/uberfire-client-api/src/main/java/org/uberfire/client/annotations/WorkbenchScreen.java b/uberfire-client-api/src/main/java/org/uberfire/client/annotations/WorkbenchScreen.java index f494af39e9..6eec09d142 100644 --- a/uberfire-client-api/src/main/java/org/uberfire/client/annotations/WorkbenchScreen.java +++ b/uberfire-client-api/src/main/java/org/uberfire/client/annotations/WorkbenchScreen.java @@ -80,4 +80,12 @@ * is the trigger to create a new panel, if panel already exists this information is ignored. */ int preferredWidth() default -1; + + /** + * Indicates that this screen can be discovered and loaded at runtime. + * This is useful when building plugins or extensions where the screen + * is part of an external script loaded at runtime, as opposed to being + * statically compiled into the main application. + */ + boolean isDynamic() default false; } diff --git a/uberfire-client-api/src/main/java/org/uberfire/client/mvp/LockTarget.java b/uberfire-client-api/src/main/java/org/uberfire/client/mvp/LockTarget.java index 87f65ae831..3e19d6c90d 100644 --- a/uberfire-client-api/src/main/java/org/uberfire/client/mvp/LockTarget.java +++ b/uberfire-client-api/src/main/java/org/uberfire/client/mvp/LockTarget.java @@ -16,17 +16,23 @@ package org.uberfire.client.mvp; -import com.google.gwt.user.client.ui.IsWidget; +import static org.uberfire.commons.validation.PortablePreconditions.checkNotNull; + import org.uberfire.backend.vfs.Path; import org.uberfire.mvp.PlaceRequest; -import static org.uberfire.commons.validation.PortablePreconditions.*; +import com.google.gwt.user.client.ui.IsWidget; + +import jsinterop.annotations.JsIgnore; +import jsinterop.annotations.JsType; /** * Holds information about the target of a lock. */ +@JsType public class LockTarget { + @JsType public interface TitleProvider { String getTitle(); @@ -39,6 +45,7 @@ public interface TitleProvider { private final TitleProvider titleProvider; private final Runnable reloadRunnable; + @JsIgnore public LockTarget( Path path, IsWidget isWidget, PlaceRequest place, @@ -62,6 +69,7 @@ public Path getPath() { return path; } + @JsIgnore public IsWidget getWidget() { return isWidget; } @@ -74,6 +82,7 @@ public String getTitle() { return titleProvider.getTitle(); } + @JsIgnore public Runnable getReloadRunnable() { return reloadRunnable; } diff --git a/uberfire-client-api/src/main/java/org/uberfire/client/workbench/type/ClientResourceType.java b/uberfire-client-api/src/main/java/org/uberfire/client/workbench/type/ClientResourceType.java index 4c1666a6cb..199e5674a2 100644 --- a/uberfire-client-api/src/main/java/org/uberfire/client/workbench/type/ClientResourceType.java +++ b/uberfire-client-api/src/main/java/org/uberfire/client/workbench/type/ClientResourceType.java @@ -16,18 +16,26 @@ package org.uberfire.client.workbench.type; -import com.google.gwt.user.client.ui.IsWidget; import org.uberfire.workbench.type.ResourceTypeDefinition; +import com.google.gwt.user.client.ui.IsWidget; + +import jsinterop.annotations.JsIgnore; +import jsinterop.annotations.JsType; + /** * */ +@JsType public interface ClientResourceType extends ResourceTypeDefinition { /** * An icon representing the resource type * @return the icon */ - public IsWidget getIcon(); + @JsIgnore + default IsWidget getIcon() { + return null; + } } diff --git a/uberfire-extensions/uberfire-commons-editor/uberfire-commons-editor-client/src/main/java/org/uberfire/ext/editor/commons/client/history/SaveButton.java b/uberfire-extensions/uberfire-commons-editor/uberfire-commons-editor-client/src/main/java/org/uberfire/ext/editor/commons/client/history/SaveButton.java index 6b404ece53..ea99002940 100644 --- a/uberfire-extensions/uberfire-commons-editor/uberfire-commons-editor-client/src/main/java/org/uberfire/ext/editor/commons/client/history/SaveButton.java +++ b/uberfire-extensions/uberfire-commons-editor/uberfire-commons-editor-client/src/main/java/org/uberfire/ext/editor/commons/client/history/SaveButton.java @@ -16,12 +16,6 @@ package org.uberfire.ext.editor.commons.client.history; -import java.util.Collection; - -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.user.client.ui.Widget; import org.gwtbootstrap3.client.ui.Button; import org.gwtbootstrap3.client.ui.constants.ButtonSize; import org.uberfire.ext.editor.commons.client.resources.i18n.CommonConstants; @@ -31,6 +25,11 @@ import org.uberfire.workbench.model.menu.MenuPosition; import org.uberfire.workbench.model.menu.MenuVisitor; +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.user.client.ui.Widget; + public class SaveButton implements MenuCustom { diff --git a/uberfire-extensions/uberfire-commons-editor/uberfire-commons-editor-client/src/main/java/org/uberfire/ext/editor/commons/client/history/VersionMenuItem.java b/uberfire-extensions/uberfire-commons-editor/uberfire-commons-editor-client/src/main/java/org/uberfire/ext/editor/commons/client/history/VersionMenuItem.java index 5596b2fa41..e1370197a8 100644 --- a/uberfire-extensions/uberfire-commons-editor/uberfire-commons-editor-client/src/main/java/org/uberfire/ext/editor/commons/client/history/VersionMenuItem.java +++ b/uberfire-extensions/uberfire-commons-editor/uberfire-commons-editor-client/src/main/java/org/uberfire/ext/editor/commons/client/history/VersionMenuItem.java @@ -16,14 +16,13 @@ package org.uberfire.ext.editor.commons.client.history; -import java.util.Collection; - -import com.google.gwt.user.client.ui.Widget; 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; +import com.google.gwt.user.client.ui.Widget; + public class VersionMenuItem implements MenuCustom { @@ -82,4 +81,5 @@ public void addEnabledStateChangeListener( EnabledStateChangeListener listener ) public String getIdentifier() { return null; } + } diff --git a/uberfire-extensions/uberfire-runtime-plugins/uberfire-runtime-plugins-client/src/main/java/org/uberfire/ext/plugin/client/RuntimePluginsEntryPoint.java b/uberfire-extensions/uberfire-runtime-plugins/uberfire-runtime-plugins-client/src/main/java/org/uberfire/ext/plugin/client/RuntimePluginsEntryPoint.java index 89312f9741..cf6d358b27 100644 --- a/uberfire-extensions/uberfire-runtime-plugins/uberfire-runtime-plugins-client/src/main/java/org/uberfire/ext/plugin/client/RuntimePluginsEntryPoint.java +++ b/uberfire-extensions/uberfire-runtime-plugins/uberfire-runtime-plugins-client/src/main/java/org/uberfire/ext/plugin/client/RuntimePluginsEntryPoint.java @@ -26,6 +26,7 @@ import org.jboss.errai.common.client.api.Caller; import org.jboss.errai.common.client.api.RemoteCallback; import org.jboss.errai.ioc.client.api.AfterInitialization; +import org.jboss.errai.ioc.client.api.EnabledByProperty; import org.jboss.errai.ioc.client.api.EntryPoint; import org.jboss.errai.ui.shared.api.annotations.Bundle; import org.uberfire.client.mvp.Activity; @@ -52,6 +53,7 @@ @EntryPoint @Bundle( "resources/i18n/Constants.properties" ) +@EnabledByProperty(value = "uberfire.plugin.mode.active", negated = true) public class RuntimePluginsEntryPoint { @Inject diff --git a/uberfire-extensions/uberfire-runtime-plugins/uberfire-runtime-plugins-client/src/main/java/org/uberfire/ext/plugin/client/perspective/editor/generator/PerspectiveEditorActivity.java b/uberfire-extensions/uberfire-runtime-plugins/uberfire-runtime-plugins-client/src/main/java/org/uberfire/ext/plugin/client/perspective/editor/generator/PerspectiveEditorActivity.java index bd309c8d42..4f43e105a5 100644 --- a/uberfire-extensions/uberfire-runtime-plugins/uberfire-runtime-plugins-client/src/main/java/org/uberfire/ext/plugin/client/perspective/editor/generator/PerspectiveEditorActivity.java +++ b/uberfire-extensions/uberfire-runtime-plugins/uberfire-runtime-plugins-client/src/main/java/org/uberfire/ext/plugin/client/perspective/editor/generator/PerspectiveEditorActivity.java @@ -16,15 +16,11 @@ package org.uberfire.ext.plugin.client.perspective.editor.generator; -import java.util.Collection; -import java.util.Collections; - import org.uberfire.client.mvp.PerspectiveActivity; import org.uberfire.client.workbench.panels.impl.SimpleWorkbenchPanelPresenter; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; 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.PartDefinition; @@ -102,11 +98,6 @@ public String getIdentifier() { return editor.getName(); } - @Override - public ResourceType getResourceType() { - return ActivityResourceType.PERSPECTIVE; - } - @Override public boolean isDefault() { return false; @@ -126,4 +117,10 @@ public Menus getMenus() { public ToolBar getToolBar() { return null; } + + @Override + public ActivityResourceType getResourceType() { + return ActivityResourceType.PERSPECTIVE; + } + } diff --git a/uberfire-extensions/uberfire-runtime-plugins/uberfire-runtime-plugins-client/src/main/java/org/uberfire/ext/plugin/client/perspective/editor/generator/PerspectiveEditorScreenActivity.java b/uberfire-extensions/uberfire-runtime-plugins/uberfire-runtime-plugins-client/src/main/java/org/uberfire/ext/plugin/client/perspective/editor/generator/PerspectiveEditorScreenActivity.java index a6be5b0e34..2d597bceb2 100644 --- a/uberfire-extensions/uberfire-runtime-plugins/uberfire-runtime-plugins-client/src/main/java/org/uberfire/ext/plugin/client/perspective/editor/generator/PerspectiveEditorScreenActivity.java +++ b/uberfire-extensions/uberfire-runtime-plugins/uberfire-runtime-plugins-client/src/main/java/org/uberfire/ext/plugin/client/perspective/editor/generator/PerspectiveEditorScreenActivity.java @@ -16,21 +16,19 @@ package org.uberfire.ext.plugin.client.perspective.editor.generator; -import com.google.gwt.user.client.Window; -import com.google.gwt.user.client.ui.FlowPanel; -import com.google.gwt.user.client.ui.IsWidget; -import com.google.gwt.user.client.ui.Panel; 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.mvp.PlaceRequest; +import org.uberfire.workbench.model.ActivityResourceType; import org.uberfire.workbench.model.NamedPosition; import org.uberfire.workbench.model.Position; import org.uberfire.workbench.model.menu.Menus; import org.uberfire.workbench.model.toolbar.ToolBar; -import java.util.Collection; -import java.util.Collections; +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.IsWidget; +import com.google.gwt.user.client.ui.Panel; public class PerspectiveEditorScreenActivity implements WorkbenchScreenActivity { @@ -143,12 +141,8 @@ public String contextId() { } @Override - public Integer preferredHeight() { - return null; - } - - @Override - public Integer preferredWidth() { - return null; + public ActivityResourceType getResourceType() { + return ActivityResourceType.SCREEN; } + } diff --git a/uberfire-js/src/main/java/org/uberfire/client/JSEntryPoint.java b/uberfire-js/src/main/java/org/uberfire/client/JSEntryPoint.java index 2e1e62b30c..9ca7355827 100644 --- a/uberfire-js/src/main/java/org/uberfire/client/JSEntryPoint.java +++ b/uberfire-js/src/main/java/org/uberfire/client/JSEntryPoint.java @@ -24,6 +24,7 @@ import javax.inject.Inject; import org.jboss.errai.ioc.client.api.AfterInitialization; +import org.jboss.errai.ioc.client.api.EnabledByProperty; import org.jboss.errai.ioc.client.api.EntryPoint; import org.uberfire.client.plugin.RuntimePluginsServiceProxy; import org.uberfire.client.workbench.Workbench; @@ -32,6 +33,7 @@ import com.google.gwt.core.client.ScriptInjector; @EntryPoint +@EnabledByProperty(value = "uberfire.plugin.mode.active", negated = true) public class JSEntryPoint { @Inject diff --git a/uberfire-js/src/main/java/org/uberfire/client/editor/JSEditorActivity.java b/uberfire-js/src/main/java/org/uberfire/client/editor/JSEditorActivity.java index a3e914a564..5240d2b8ba 100644 --- a/uberfire-js/src/main/java/org/uberfire/client/editor/JSEditorActivity.java +++ b/uberfire-js/src/main/java/org/uberfire/client/editor/JSEditorActivity.java @@ -15,8 +15,7 @@ */ package org.uberfire.client.editor; -import java.util.Collection; -import java.util.Collections; +import javax.enterprise.inject.Alternative; import org.uberfire.backend.vfs.ObservablePath; import org.uberfire.client.mvp.AbstractWorkbenchEditorActivity; @@ -28,8 +27,6 @@ import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.IsWidget; -import javax.enterprise.inject.Alternative; - @Alternative public class JSEditorActivity extends AbstractWorkbenchEditorActivity { diff --git a/uberfire-js/src/main/java/org/uberfire/client/jsapi/JSPlaceRequest.java b/uberfire-js/src/main/java/org/uberfire/client/jsapi/JSPlaceRequest.java index df69e47e57..e7a3e52cc6 100644 --- a/uberfire-js/src/main/java/org/uberfire/client/jsapi/JSPlaceRequest.java +++ b/uberfire-js/src/main/java/org/uberfire/client/jsapi/JSPlaceRequest.java @@ -61,8 +61,8 @@ public static JSPlaceRequest fromPlaceRequest( PlaceRequest pr ) { JSPlaceRequest jspr = newInstance(); jspr.setIdentifier( pr.getIdentifier() ); JSONObject rawParams = new JSONObject(); - for ( Map.Entry param : pr.getParameters().entrySet() ) { - rawParams.put( param.getKey(), new JSONString( param.getValue() ) ); + for ( String name : pr.getParameterNames() ) { + rawParams.put( name, new JSONString( pr.getParameters().get( name )) ); } jspr.setParams( rawParams.getJavaScriptObject() ); return jspr; diff --git a/uberfire-js/src/main/java/org/uberfire/client/screen/JSWorkbenchScreenActivity.java b/uberfire-js/src/main/java/org/uberfire/client/screen/JSWorkbenchScreenActivity.java index 1b5d6ceafe..51a61c4aa8 100644 --- a/uberfire-js/src/main/java/org/uberfire/client/screen/JSWorkbenchScreenActivity.java +++ b/uberfire-js/src/main/java/org/uberfire/client/screen/JSWorkbenchScreenActivity.java @@ -16,16 +16,11 @@ package org.uberfire.client.screen; -import java.util.List; import javax.enterprise.inject.Alternative; -import com.google.gwt.core.client.Scheduler; -import com.google.gwt.user.client.ui.HTML; -import com.google.gwt.user.client.ui.IsWidget; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.mvp.WorkbenchScreenActivity; import org.uberfire.mvp.PlaceRequest; -import org.uberfire.security.Resource; import org.uberfire.security.ResourceType; import org.uberfire.workbench.model.ActivityResourceType; import org.uberfire.workbench.model.CompassPosition; @@ -33,6 +28,10 @@ import org.uberfire.workbench.model.menu.Menus; import org.uberfire.workbench.model.toolbar.ToolBar; +import com.google.gwt.core.client.Scheduler; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.IsWidget; + @Alternative public class JSWorkbenchScreenActivity implements WorkbenchScreenActivity { @@ -171,12 +170,13 @@ public String contextId() { } @Override - public Integer preferredHeight() { - return null; + public int preferredHeight() { + return -1; } @Override - public Integer preferredWidth() { - return null; + public int preferredWidth() { + return -1; } + } diff --git a/uberfire-js/src/main/java/org/uberfire/client/splash/JSSplashScreenActivity.java b/uberfire-js/src/main/java/org/uberfire/client/splash/JSSplashScreenActivity.java index cab9182fdf..06da2fd36e 100644 --- a/uberfire-js/src/main/java/org/uberfire/client/splash/JSSplashScreenActivity.java +++ b/uberfire-js/src/main/java/org/uberfire/client/splash/JSSplashScreenActivity.java @@ -15,18 +15,15 @@ */ package org.uberfire.client.splash; -import java.util.List; - import com.google.gwt.event.logical.shared.CloseEvent; import com.google.gwt.event.logical.shared.CloseHandler; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.IsWidget; + import org.uberfire.client.mvp.SplashScreenActivity; -import org.uberfire.client.screen.JSNativeScreen; import org.uberfire.client.workbench.widgets.splash.SplashView; import org.uberfire.mvp.ParameterizedCommand; import org.uberfire.mvp.PlaceRequest; -import org.uberfire.security.Resource; import org.uberfire.security.ResourceType; import org.uberfire.workbench.model.ActivityResourceType; import org.uberfire.workbench.model.SplashScreenFilter; diff --git a/uberfire-security/uberfire-security-api/src/main/java/org/uberfire/security/impl/authz/DefaultAuthorizationManager.java b/uberfire-security/uberfire-security-api/src/main/java/org/uberfire/security/impl/authz/DefaultAuthorizationManager.java index 53ace41ad4..76d650bf16 100644 --- a/uberfire-security/uberfire-security-api/src/main/java/org/uberfire/security/impl/authz/DefaultAuthorizationManager.java +++ b/uberfire-security/uberfire-security-api/src/main/java/org/uberfire/security/impl/authz/DefaultAuthorizationManager.java @@ -33,6 +33,7 @@ import org.uberfire.security.authz.VotingStrategy; import static org.uberfire.commons.validation.PortablePreconditions.*; +import static org.uberfire.plugin.PluginUtil.*; @ApplicationScoped public class DefaultAuthorizationManager implements AuthorizationManager { @@ -76,7 +77,7 @@ public boolean authorize(Resource resource, ResourceAction action, User user, Vo if (deps != null && !deps.isEmpty()) { // One dep is accessible - for (Resource dep : deps) { + for (Resource dep : ensureIterable ( deps ) ) { boolean itemAccess = authorize(dep, action, user); if (itemAccess) { return true; diff --git a/uberfire-security/uberfire-security-api/src/main/java/org/uberfire/security/impl/authz/DefaultPermissionManager.java b/uberfire-security/uberfire-security-api/src/main/java/org/uberfire/security/impl/authz/DefaultPermissionManager.java index cc501c22ff..4c52da958c 100644 --- a/uberfire-security/uberfire-security-api/src/main/java/org/uberfire/security/impl/authz/DefaultPermissionManager.java +++ b/uberfire-security/uberfire-security-api/src/main/java/org/uberfire/security/impl/authz/DefaultPermissionManager.java @@ -110,7 +110,7 @@ public Permission createPermission(Resource resource, ResourceAction action, boo // Does the resource have a type? // YES => check the resource action f.i: "project.read.myprojectid" - if (resource.getResourceType() != null && !resource.getResourceType().equals(ResourceType.UNKNOWN)) { + if ( resource.getResourceType() != null && !resource.isType( ResourceType.UNKNOWN.getName() ) ) { PermissionType permissionType = permissionTypeRegistry.resolve(resource.getResourceType().getName()); return permissionType.createPermission(resource, action, granted); } diff --git a/uberfire-security/uberfire-security-api/src/main/java/org/uberfire/security/impl/authz/DotNamedPermissionType.java b/uberfire-security/uberfire-security-api/src/main/java/org/uberfire/security/impl/authz/DotNamedPermissionType.java index b2bb8b7c20..339a9c1931 100644 --- a/uberfire-security/uberfire-security-api/src/main/java/org/uberfire/security/impl/authz/DotNamedPermissionType.java +++ b/uberfire-security/uberfire-security-api/src/main/java/org/uberfire/security/impl/authz/DotNamedPermissionType.java @@ -78,7 +78,7 @@ public String resolveResourceId(Permission permission) { protected String buildPermissionName(ResourceType type, String action, String resourceId) { String name = ""; - if (type != null && !type.equals(ResourceType.UNKNOWN)) { + if (type != null && !type.getName().equalsIgnoreCase( ResourceType.UNKNOWN.getName() ) ) { name += type.getName(); } if (action != null && action.trim().length() > 0) { diff --git a/uberfire-showcase/uberfire-client-webapp/src/main/resources/org/uberfire/FastCompiledUberfireShowcaseClient.gwt.xml b/uberfire-showcase/uberfire-client-webapp/src/main/resources/org/uberfire/FastCompiledUberfireShowcaseClient.gwt.xml index fa4dd9987f..0f8876f602 100644 --- a/uberfire-showcase/uberfire-client-webapp/src/main/resources/org/uberfire/FastCompiledUberfireShowcaseClient.gwt.xml +++ b/uberfire-showcase/uberfire-client-webapp/src/main/resources/org/uberfire/FastCompiledUberfireShowcaseClient.gwt.xml @@ -24,4 +24,7 @@ + + + diff --git a/uberfire-showcase/uberfire-client-webapp/src/main/resources/org/uberfire/UberfireShowcaseClient.gwt.xml b/uberfire-showcase/uberfire-client-webapp/src/main/resources/org/uberfire/UberfireShowcaseClient.gwt.xml index 34b22a15b2..9f64e22037 100644 --- a/uberfire-showcase/uberfire-client-webapp/src/main/resources/org/uberfire/UberfireShowcaseClient.gwt.xml +++ b/uberfire-showcase/uberfire-client-webapp/src/main/resources/org/uberfire/UberfireShowcaseClient.gwt.xml @@ -43,4 +43,8 @@ + + + + diff --git a/uberfire-showcase/uberfire-dynamic-plugin/.gitignore b/uberfire-showcase/uberfire-dynamic-plugin/.gitignore new file mode 100644 index 0000000000..52a7a193d2 --- /dev/null +++ b/uberfire-showcase/uberfire-dynamic-plugin/.gitignore @@ -0,0 +1,17 @@ +/target +/local +src/main/webapp/WEB-INF/ +src/main/gwt-unitCache/ +src/main/webapp/org.uberfire.UberfireDynamicPlugin/ + +# Eclipse, Netbeans and IntelliJ files +/.* +/**/.* +!.gitignore +/nbproject +/*.ipr +/*.iws +/*.iml + +# Repository wide ignore mac DS_Store files +.DS_Store diff --git a/uberfire-showcase/uberfire-dynamic-plugin/README.md b/uberfire-showcase/uberfire-dynamic-plugin/README.md new file mode 100644 index 0000000000..6e94f83bd7 --- /dev/null +++ b/uberfire-showcase/uberfire-dynamic-plugin/README.md @@ -0,0 +1,38 @@ +UberFire Dynamic Plugin +======== + +This is a dynamic plugin project for UberFire. It demonstrates development of runtime +plugins using the Errai/UberFire programming model. Currently plugins are packaged as +standard .jar files containing a /js subdir for all compiled JavaScript files. + +Plugin jars can be deployed to UberFire's /plugin directory (e.g. in UberFire Showcase) +either before an UberFire application starts or at runtime. The plugins are processed and +the contained JavaScript files are injected into the DOM by Errai's ScriptInjector before +the main application script is executed. This makes all perspectives, editors, screens, as +well as all other activity beans available to Errai's bean manager without requiring any +hand-written registration logic. When UberFire applications bootstrap, all activities of +all deployed plugins are automatically available. + +This specific demo plugin provides a dynamic perspective with a custom menu and a dynamic +screen and editor. Once the .jar is deployed to the plugin dir of UberFire Showcase, the +plugin is processsed and the browser will prompt the user to activate the plugin. After +that the plugin's perspective, its screens and editors will be available to the application. + +Future steps +======================== +1. Define an app bundle format to replace the .jar format and hold both client and server-side plugin code +1. Refactor UberFire to allow for fine-grained module reuse to shrink the compiled plugin size +1. Implement an UberFire marketplace to register / browse / download plugins + +Notes +======================== +1. The dynamic GWT plugin mechanism works side-by-side with the original plain JavaScript plugin mechanism in UberFire + +Giving it a try +======================== +1. Run `mvn clean gwt:run` in uberfire-showcase +2. Launch the showcase +3. Run `mvn clean install` in uberfire-dynamic-plugin +4. Copy `uberfire-dynamic-plugin/target/uberfire-dynamic-plugin.jar` to the showcase's plugin directory (`uberfire-showcase/src/main/webapp/plugins`) +5. A popup should appear after a few seconds indicating that a new plugins is available +6. After clicking OK, there should be a new perspective available (dynamic perspective), which contains a dynamic screen and editor (bound to a dynamic resource type) \ No newline at end of file diff --git a/uberfire-showcase/uberfire-dynamic-plugin/pom.xml b/uberfire-showcase/uberfire-dynamic-plugin/pom.xml new file mode 100644 index 0000000000..e6dbc39cec --- /dev/null +++ b/uberfire-showcase/uberfire-dynamic-plugin/pom.xml @@ -0,0 +1,127 @@ + + + + + + 4.0.0 + + org.uberfire + uberfire-parent + 1.0.0-SNAPSHOT + ../../pom.xml + + + uberfire-dynamic-plugin + jar + + UberFire Dynamic Plugin + UberFire Dynamic Plugin + + + + org.uberfire + uberfire-client-api + + + + org.uberfire + uberfire-workbench-client-views-patternfly + + + + org.uberfire + uberfire-workbench-processors + + + + javax.inject + javax.inject + provided + + + + org.jboss.errai + errai-javax-enterprise + + + + org.jboss.errai + errai-ioc + + + + org.jboss.errai + errai-cdi-jboss + + + + com.google.gwt + gwt-user + provided + + + + + + ${project.artifactId} + src/main/webapp/WEB-INF/classes + + + + org.codehaus.mojo + gwt-maven-plugin + + -Xmx2G -Derrai.ioc.reachability=Aggressive -Duberfire.plugin.mode.active=true -Derrai.ioc.jsinterop.support=true + INFO + org.uberfire.UberfireDynamicPlugin + dynamic-plugin.html + src/main/webapp + true + ${project.build.outputDirectory}/js + + org.uberfire:uberfire-commons + org.uberfire:uberfire-api + org.uberfire:uberfire-nio2-model + 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-views-patternfly + + + + + gwt-clean + clean + + clean + + + + gwt-compile + + compile + + + + + + + + + diff --git a/uberfire-showcase/uberfire-dynamic-plugin/src/main/java/org/uberfire/client/editor/DynamicEditorPresenter.java b/uberfire-showcase/uberfire-dynamic-plugin/src/main/java/org/uberfire/client/editor/DynamicEditorPresenter.java new file mode 100644 index 0000000000..dfbbf1fd5b --- /dev/null +++ b/uberfire-showcase/uberfire-dynamic-plugin/src/main/java/org/uberfire/client/editor/DynamicEditorPresenter.java @@ -0,0 +1,46 @@ +/* + * 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.client.editor; + +import javax.enterprise.context.Dependent; +import javax.inject.Inject; + +import org.uberfire.client.annotations.WorkbenchEditor; +import org.uberfire.client.annotations.WorkbenchPartTitle; +import org.uberfire.client.annotations.WorkbenchPartView; +import org.uberfire.client.screen.DynamicResourceType; + +import com.google.gwt.user.client.ui.IsWidget; + +@Dependent +@WorkbenchEditor( identifier = "DynamicEditor", isDynamic = true, supportedTypes = {DynamicResourceType.class} ) +public class DynamicEditorPresenter { + + @Inject + private DynamicEditorView editor; + + @WorkbenchPartTitle + public String getTitle() { + return "Dynamic Editor"; + } + + @WorkbenchPartView + public IsWidget asWidget() { + return editor.asWidget(); + } + +} diff --git a/uberfire-showcase/uberfire-dynamic-plugin/src/main/java/org/uberfire/client/editor/DynamicEditorView.html b/uberfire-showcase/uberfire-dynamic-plugin/src/main/java/org/uberfire/client/editor/DynamicEditorView.html new file mode 100644 index 0000000000..d35d2f595e --- /dev/null +++ b/uberfire-showcase/uberfire-dynamic-plugin/src/main/java/org/uberfire/client/editor/DynamicEditorView.html @@ -0,0 +1,6 @@ +
+

Hello World!

+

This is an editor from a dynamically loaded plugin.

+ + +
\ No newline at end of file diff --git a/uberfire-showcase/uberfire-dynamic-plugin/src/main/java/org/uberfire/client/editor/DynamicEditorView.java b/uberfire-showcase/uberfire-dynamic-plugin/src/main/java/org/uberfire/client/editor/DynamicEditorView.java new file mode 100644 index 0000000000..2124f1d001 --- /dev/null +++ b/uberfire-showcase/uberfire-dynamic-plugin/src/main/java/org/uberfire/client/editor/DynamicEditorView.java @@ -0,0 +1,18 @@ +package org.uberfire.client.editor; + +import javax.inject.Inject; + +import org.jboss.errai.ui.shared.api.annotations.DataField; +import org.jboss.errai.ui.shared.api.annotations.Templated; + +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.TextArea; + +@Templated +public class DynamicEditorView extends Composite { + + @Inject + @DataField("text-area") + private TextArea textArea; + +} \ No newline at end of file diff --git a/uberfire-showcase/uberfire-dynamic-plugin/src/main/java/org/uberfire/client/perspective/DynamicPerspective.java b/uberfire-showcase/uberfire-dynamic-plugin/src/main/java/org/uberfire/client/perspective/DynamicPerspective.java new file mode 100644 index 0000000000..b2e2c59408 --- /dev/null +++ b/uberfire-showcase/uberfire-dynamic-plugin/src/main/java/org/uberfire/client/perspective/DynamicPerspective.java @@ -0,0 +1,95 @@ +/* + * 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.client.perspective; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; + +import org.jboss.errai.ioc.client.api.Shared; +import org.uberfire.backend.vfs.PathFactory; +import org.uberfire.client.annotations.Perspective; +import org.uberfire.client.annotations.WorkbenchMenu; +import org.uberfire.client.annotations.WorkbenchPerspective; +import org.uberfire.client.mvp.PlaceManager; +import org.uberfire.client.workbench.panels.impl.SimpleWorkbenchPanelPresenter; +import org.uberfire.mvp.Command; +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 org.uberfire.workbench.model.menu.MenuFactory; +import org.uberfire.workbench.model.menu.Menus; + +import com.google.gwt.user.client.Window; + +@ApplicationScoped +@WorkbenchPerspective(identifier = "DynamicPerspective", isDynamic = true) +public class DynamicPerspective { + + @Inject @Shared + private PlaceManager placeManager; + + @Perspective + public PerspectiveDefinition buildPerspective() { + final PerspectiveDefinition p = new PerspectiveDefinitionImpl( SimpleWorkbenchPanelPresenter.class.getName() ); + p.getRoot().addPart( new PartDefinitionImpl( new DefaultPlaceRequest( "DynamicScreen" ) ) ); + p.setName( "Dynamic Perspective" ); + return p; + } + + @WorkbenchMenu + public Menus getMenus() { + return MenuFactory + .newTopLevelMenu( "Dynamic Menu" ).respondsWith( new Command() { + @Override + public void execute() { + Window.alert( "Hello from a dynamic menu!" ); + } + } ) + .endMenu() + .newTopLevelMenu( "Open Dynamic Editor" ).respondsWith( new Command() { + @Override + public void execute() { + placeManager.goTo("DynamicEditor"); + } + } ) + .endMenu() + .newTopLevelMenu( "Open Dynamic Screen" ) + .respondsWith( new Command() { + @Override + public void execute() { + placeManager.goTo("DynamicScreen"); + } + } ) + .endMenu() + .newTopLevelMenu( "Create New" ) + .menus() + // Test that an editor from a dynamic plugin can be opened for a dynamic resource type + .menu( "File matching dynamically loaded resource type" ) + .respondsWith( new Command() { + @Override + public void execute() { + placeManager.goTo(PathFactory.newPath( "test.csa", "default://project/" )); + } + } ) + .endMenu() + .endMenus() + .endMenu() + .build(); + } + +} diff --git a/uberfire-showcase/uberfire-dynamic-plugin/src/main/java/org/uberfire/client/screen/DynamicResourceType.java b/uberfire-showcase/uberfire-dynamic-plugin/src/main/java/org/uberfire/client/screen/DynamicResourceType.java new file mode 100644 index 0000000000..c1f2e633c6 --- /dev/null +++ b/uberfire-showcase/uberfire-dynamic-plugin/src/main/java/org/uberfire/client/screen/DynamicResourceType.java @@ -0,0 +1,64 @@ +/* + * 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.client.screen; + +import javax.enterprise.context.ApplicationScoped; + +import org.uberfire.backend.vfs.Path; +import org.uberfire.client.workbench.type.ClientResourceType; + +import jsinterop.annotations.JsType; + +@ApplicationScoped +@JsType +public class DynamicResourceType implements ClientResourceType { + + @Override + public String getShortName() { + return "test"; + } + + @Override + public String getDescription() { + return "my test desc"; + } + + @Override + public String getPrefix() { + return ""; + } + + @Override + public String getSuffix() { + return "csa"; + } + + @Override + public int getPriority() { + return Integer.MAX_VALUE; + } + + @Override + public String getSimpleWildcardPattern() { + return "*." + getSuffix(); + } + + @Override + public boolean accept( final Path path ) { + return path.getFileName().endsWith( "." + getSuffix() ); + } +} diff --git a/uberfire-showcase/uberfire-dynamic-plugin/src/main/java/org/uberfire/client/screen/DynamicScreen.html b/uberfire-showcase/uberfire-dynamic-plugin/src/main/java/org/uberfire/client/screen/DynamicScreen.html new file mode 100644 index 0000000000..d4627fe6f4 --- /dev/null +++ b/uberfire-showcase/uberfire-dynamic-plugin/src/main/java/org/uberfire/client/screen/DynamicScreen.html @@ -0,0 +1,21 @@ + +
+

Hello World!

+

This is a screen from a dynamically loaded plugin.

+ + +
diff --git a/uberfire-showcase/uberfire-dynamic-plugin/src/main/java/org/uberfire/client/screen/DynamicScreen.java b/uberfire-showcase/uberfire-dynamic-plugin/src/main/java/org/uberfire/client/screen/DynamicScreen.java new file mode 100644 index 0000000000..0f98d0fd37 --- /dev/null +++ b/uberfire-showcase/uberfire-dynamic-plugin/src/main/java/org/uberfire/client/screen/DynamicScreen.java @@ -0,0 +1,52 @@ +/* + * 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.client.screen; + +import javax.enterprise.context.Dependent; +import javax.inject.Inject; + +import org.jboss.errai.common.client.dom.Button; +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.annotations.WorkbenchPartTitle; +import org.uberfire.client.annotations.WorkbenchScreen; + +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.Composite; + +@Dependent +@WorkbenchScreen( identifier = "DynamicScreen", isDynamic = true ) +@Templated +public class DynamicScreen extends Composite { + + @Inject @DataField + private Button hello; + + @WorkbenchPartTitle + public String getName() { + return "Dynamic Screen"; + } + + @EventHandler("hello") + private void onClick(ClickEvent e) { + // Test Errai UI / DOM event handlers from dynamically loaded plugin screen + Window.alert( "Hello!" ); + } + +} diff --git a/uberfire-showcase/uberfire-dynamic-plugin/src/main/resources/ErraiApp.properties b/uberfire-showcase/uberfire-dynamic-plugin/src/main/resources/ErraiApp.properties new file mode 100644 index 0000000000..e38c39c86c --- /dev/null +++ b/uberfire-showcase/uberfire-dynamic-plugin/src/main/resources/ErraiApp.properties @@ -0,0 +1 @@ +errai.ioc.enabled.alternatives=org.uberfire.client.workbench.WorkbenchServicesProxyClientImpl \ No newline at end of file diff --git a/uberfire-showcase/uberfire-dynamic-plugin/src/main/resources/META-INF/beans.xml b/uberfire-showcase/uberfire-dynamic-plugin/src/main/resources/META-INF/beans.xml new file mode 100644 index 0000000000..9d04c890e0 --- /dev/null +++ b/uberfire-showcase/uberfire-dynamic-plugin/src/main/resources/META-INF/beans.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/uberfire-showcase/uberfire-dynamic-plugin/src/main/resources/org/uberfire/UberfireDynamicPlugin.gwt.xml b/uberfire-showcase/uberfire-dynamic-plugin/src/main/resources/org/uberfire/UberfireDynamicPlugin.gwt.xml new file mode 100644 index 0000000000..d1f3cbaa9c --- /dev/null +++ b/uberfire-showcase/uberfire-dynamic-plugin/src/main/resources/org/uberfire/UberfireDynamicPlugin.gwt.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/uberfire-showcase/uberfire-dynamic-plugin/src/main/webapp/dynamic-plugin.html b/uberfire-showcase/uberfire-dynamic-plugin/src/main/webapp/dynamic-plugin.html new file mode 100644 index 0000000000..f0d290db27 --- /dev/null +++ b/uberfire-showcase/uberfire-dynamic-plugin/src/main/webapp/dynamic-plugin.html @@ -0,0 +1,28 @@ + + + + + + + + UberFire Showcase + + + + + + diff --git a/uberfire-showcase/uberfire-webapp/pom.xml b/uberfire-showcase/uberfire-webapp/pom.xml index 1566604aad..64c0068c6b 100644 --- a/uberfire-showcase/uberfire-webapp/pom.xml +++ b/uberfire-showcase/uberfire-webapp/pom.xml @@ -37,6 +37,7 @@ + org.uberfire uberfire-all @@ -248,17 +249,17 @@ org.codehaus.mojo gwt-maven-plugin - -Xmx2G -XX:CompileThreshold=7000 -Derrai.jboss.home=${errai.jboss.home} + -Xmx2G -XX:CompileThreshold=7000 -Derrai.jboss.home=${errai.jboss.home} -Derrai.ioc.jsinterop.support=true true INFO false org.jboss.errai.cdi.server.gwt.EmbeddedWildFlyLauncher org.uberfire.FastCompiledUberfireShowcase true - showcase.html + index.html src/main/webapp - org.uberfire.FastCompiledUberfireShowcase - true + org.uberfire.FastCompiledUberfireShowcase + true org.uberfire:uberfire-commons diff --git a/uberfire-showcase/uberfire-webapp/src/main/java/org/uberfire/client/ShowcaseEntryPoint.java b/uberfire-showcase/uberfire-webapp/src/main/java/org/uberfire/client/ShowcaseEntryPoint.java index a2774ad88f..af3e8a48e4 100644 --- a/uberfire-showcase/uberfire-webapp/src/main/java/org/uberfire/client/ShowcaseEntryPoint.java +++ b/uberfire-showcase/uberfire-webapp/src/main/java/org/uberfire/client/ShowcaseEntryPoint.java @@ -15,6 +15,9 @@ */ package org.uberfire.client; +import static org.uberfire.workbench.model.menu.MenuFactory.newTopLevelCustomMenu; +import static org.uberfire.workbench.model.menu.MenuFactory.newTopLevelMenu; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -22,19 +25,13 @@ import java.util.Iterator; import java.util.List; import java.util.Set; + import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Observes; import javax.enterprise.inject.Produces; import javax.inject.Inject; -import com.google.common.collect.Sets; -import com.google.gwt.animation.client.Animation; -import com.google.gwt.dom.client.Element; -import com.google.gwt.dom.client.Style; -import com.google.gwt.user.client.Window; -import com.google.gwt.user.client.ui.Image; -import com.google.gwt.user.client.ui.RootPanel; -import com.google.gwt.user.client.ui.Widget; +import org.gwtbootstrap3.client.ui.html.Text; import org.jboss.errai.common.client.api.Caller; import org.jboss.errai.ioc.client.api.AfterInitialization; import org.jboss.errai.ioc.client.api.EntryPoint; @@ -57,15 +54,25 @@ import org.uberfire.client.screen.JSWorkbenchScreenActivity; import org.uberfire.client.views.pfly.menu.MainBrand; import org.uberfire.client.views.pfly.menu.UserMenu; +import org.uberfire.client.views.pfly.modal.Bs3Modal; import org.uberfire.client.workbench.events.ApplicationReadyEvent; import org.uberfire.client.workbench.widgets.menu.UtilityMenuBar; import org.uberfire.client.workbench.widgets.menu.WorkbenchMenuBar; import org.uberfire.mvp.impl.DefaultPlaceRequest; +import org.uberfire.workbench.events.NotificationEvent; +import org.uberfire.workbench.events.PluginAddedEvent; import org.uberfire.workbench.model.menu.MenuFactory; import org.uberfire.workbench.model.menu.MenuItem; import org.uberfire.workbench.model.menu.Menus; -import static org.uberfire.workbench.model.menu.MenuFactory.*; +import com.google.common.collect.Sets; +import com.google.gwt.animation.client.Animation; +import com.google.gwt.dom.client.Element; +import com.google.gwt.dom.client.Style; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.Image; +import com.google.gwt.user.client.ui.RootPanel; +import com.google.gwt.user.client.ui.Widget; /** * GWT's Entry-point for Uberfire-showcase @@ -99,7 +106,7 @@ public class ShowcaseEntryPoint { @Inject private SearchMenuBuilder searchMenuBuilder; - + private static final Set menuItemsToRemove = Sets.newHashSet( "IFrameScreen", "IPInfoGadget", @@ -204,7 +211,7 @@ private List getPerspectives() { if (SimplePerspectiveNoContext.SIMPLE_PERSPECTIVE_NO_CONTEXT.equals(perspective.getIdentifier())) { continue; } - final String name = perspective.getDefaultPerspectiveLayout().getName(); + final String name = perspective.getName(); final MenuItem item = MenuFactory.newSimpleItem( name ).perspective( perspective.getIdentifier() ).endMenu().build().getItems().get( 0 ); perspectives.add( item ); } @@ -252,7 +259,7 @@ private List getPerspectiveActivities() { @Override public int compare( PerspectiveActivity o1, PerspectiveActivity o2 ) { - return o1.getDefaultPerspectiveLayout().getName().compareTo( o2.getDefaultPerspectiveLayout().getName() ); + return o1.getName().compareTo( o2.getName() ); } } ); @@ -296,5 +303,14 @@ public Widget asWidget() { } }; } + + private void onPluginAvailable(@Observes PluginAddedEvent pluginEvent) { + Bs3Modal modal = new Bs3Modal(); + modal.setContent( new Text("Plugin " + pluginEvent.getName() + + " has been installed. \n A reload is required to activate it.") ); + modal.setTitle( "Plugin available" ); + modal.addHiddenHandler( evt -> Window.Location.reload()); + modal.show(); + } } diff --git a/uberfire-showcase/uberfire-webapp/src/main/java/org/uberfire/client/screens/SampleWorkbenchEditor.java b/uberfire-showcase/uberfire-webapp/src/main/java/org/uberfire/client/screens/SampleWorkbenchEditor.java index 0ac068a350..91d103bc77 100644 --- a/uberfire-showcase/uberfire-webapp/src/main/java/org/uberfire/client/screens/SampleWorkbenchEditor.java +++ b/uberfire-showcase/uberfire-webapp/src/main/java/org/uberfire/client/screens/SampleWorkbenchEditor.java @@ -27,11 +27,10 @@ import org.uberfire.client.annotations.WorkbenchPartTitle; import org.uberfire.client.annotations.WorkbenchPartView; import org.uberfire.client.views.pfly.multipage.PageImpl; -import org.uberfire.client.workbench.type.AnyResourceType; import org.uberfire.client.workbench.widgets.multipage.MultiPageEditor; @Dependent -@WorkbenchEditor( identifier = "SampleWorkbenchEditor", supportedTypes = AnyResourceType.class ) +@WorkbenchEditor( identifier = "SampleWorkbenchEditor", supportedTypes = TextResourceType.class ) public class SampleWorkbenchEditor { @Inject diff --git a/uberfire-showcase/uberfire-webapp/src/main/java/org/uberfire/client/screens/TextResourceType.java b/uberfire-showcase/uberfire-webapp/src/main/java/org/uberfire/client/screens/TextResourceType.java new file mode 100644 index 0000000000..9ed3cd8813 --- /dev/null +++ b/uberfire-showcase/uberfire-webapp/src/main/java/org/uberfire/client/screens/TextResourceType.java @@ -0,0 +1,64 @@ +/* + * 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.client.screens; + +import javax.enterprise.context.ApplicationScoped; + +import org.uberfire.backend.vfs.Path; +import org.uberfire.client.workbench.type.ClientResourceType; + +import jsinterop.annotations.JsType; + +@ApplicationScoped +@JsType +public class TextResourceType implements ClientResourceType { + + @Override + public String getShortName() { + return "text"; + } + + @Override + public String getDescription() { + return ""; + } + + @Override + public String getPrefix() { + return ""; + } + + @Override + public String getSuffix() { + return "txt"; + } + + @Override + public int getPriority() { + return 0; + } + + @Override + public String getSimpleWildcardPattern() { + return "*." + getSuffix(); + } + + @Override + public boolean accept( final Path path ) { + return path.getFileName().endsWith( "." + getSuffix() ); + } +} diff --git a/uberfire-showcase/uberfire-webapp/src/main/resources/org/uberfire/UberfireShowcase.gwt.xml b/uberfire-showcase/uberfire-webapp/src/main/resources/org/uberfire/UberfireShowcase.gwt.xml index 1eeffcf8ff..6c45fee84d 100644 --- a/uberfire-showcase/uberfire-webapp/src/main/resources/org/uberfire/UberfireShowcase.gwt.xml +++ b/uberfire-showcase/uberfire-webapp/src/main/resources/org/uberfire/UberfireShowcase.gwt.xml @@ -38,4 +38,8 @@ + + + + diff --git a/uberfire-showcase/uberfire-webapp/src/main/webapp/WEB-INF/web.xml b/uberfire-showcase/uberfire-webapp/src/main/webapp/WEB-INF/web.xml index ac3f221b76..8d41c541b4 100644 --- a/uberfire-showcase/uberfire-webapp/src/main/webapp/WEB-INF/web.xml +++ b/uberfire-showcase/uberfire-webapp/src/main/webapp/WEB-INF/web.xml @@ -21,7 +21,7 @@ host-page - /showcase.html + /index.html forceReAuthentication @@ -31,7 +31,7 @@ Security Filter - /showcase.html + /index.html @@ -51,7 +51,7 @@ Host Page Patch - /showcase.html + /index.html @@ -61,7 +61,7 @@ GWT Locale Filter - /showcase.html + /index.html diff --git a/uberfire-showcase/uberfire-webapp/src/main/webapp/showcase.html b/uberfire-showcase/uberfire-webapp/src/main/webapp/index.html similarity index 100% rename from uberfire-showcase/uberfire-webapp/src/main/webapp/showcase.html rename to uberfire-showcase/uberfire-webapp/src/main/webapp/index.html index 93d6d8560c..18a5bbdda9 100644 --- a/uberfire-showcase/uberfire-webapp/src/main/webapp/showcase.html +++ b/uberfire-showcase/uberfire-webapp/src/main/webapp/index.html @@ -18,7 +18,6 @@ - UberFire Showcase @@ -50,6 +49,7 @@

Please wait

+ diff --git a/uberfire-workbench/uberfire-workbench-client-backend/src/main/java/org/uberfire/client/RuntimePluginsServiceProxyBackendImpl.java b/uberfire-workbench/uberfire-workbench-client-backend/src/main/java/org/uberfire/client/RuntimePluginsServiceProxyBackendImpl.java index a3ed5ec63f..dff328a7ee 100644 --- a/uberfire-workbench/uberfire-workbench-client-backend/src/main/java/org/uberfire/client/RuntimePluginsServiceProxyBackendImpl.java +++ b/uberfire-workbench/uberfire-workbench-client-backend/src/main/java/org/uberfire/client/RuntimePluginsServiceProxyBackendImpl.java @@ -23,7 +23,7 @@ import org.jboss.errai.common.client.api.Caller; import org.jboss.errai.common.client.api.RemoteCallback; -import org.uberfire.backend.plugin.RuntimePluginsService; +import org.uberfire.backend.plugin.RuntimePluginService; import org.uberfire.client.plugin.RuntimePluginsServiceProxy; import org.uberfire.mvp.ParameterizedCommand; @@ -32,7 +32,7 @@ public class RuntimePluginsServiceProxyBackendImpl implements RuntimePluginsServiceProxy { @Inject - private Caller runtimePluginsService; + private Caller runtimePluginsService; @Override public void getTemplateContent( final String contentUrl, diff --git a/uberfire-workbench/uberfire-workbench-client-views-patternfly/src/main/java/org/uberfire/client/views/pfly/listbar/ListBarWidgetImpl.java b/uberfire-workbench/uberfire-workbench-client-views-patternfly/src/main/java/org/uberfire/client/views/pfly/listbar/ListBarWidgetImpl.java index d405f75310..c1289a28c6 100644 --- a/uberfire-workbench/uberfire-workbench-client-views-patternfly/src/main/java/org/uberfire/client/views/pfly/listbar/ListBarWidgetImpl.java +++ b/uberfire-workbench/uberfire-workbench-client-views-patternfly/src/main/java/org/uberfire/client/views/pfly/listbar/ListBarWidgetImpl.java @@ -57,6 +57,7 @@ import static com.google.gwt.dom.client.Style.Display.BLOCK; import static com.google.gwt.dom.client.Style.Display.NONE; +import static org.uberfire.plugin.PluginUtil.*; /** * Implementation of ListBarWidget based on PatternFly components. @@ -289,7 +290,7 @@ void setupContextMenu() { @Override public boolean remove( final PartDefinition part ) { titleDropDown.removePart( part ); - if ( currentPart.getK1().equals( part ) ) { + if ( currentPart.getK1().asString().equals( part.asString() ) ) { if ( parts.size() > 0 ) { presenter.selectPart( parts.iterator().next() ); } else { @@ -422,7 +423,7 @@ private Widget makeMenuItemCommand( final MenuItemCommand cmdItem, final boolean private Widget makeMenuGroup(final MenuGroup groups, final boolean isRoot ) { if ( isRoot ) { final List widgetList = new ArrayList<>(); - for ( final MenuItem _item : groups.getItems() ) { + for ( final MenuItem _item : ensureIterable ( groups.getItems() ) ) { final Widget widget = makeItem( _item, false ); if ( widget != null ) { widgetList.add( widget ); diff --git a/uberfire-workbench/uberfire-workbench-client-views-patternfly/src/main/java/org/uberfire/client/views/pfly/listbar/PartListDropdown.java b/uberfire-workbench/uberfire-workbench-client-views-patternfly/src/main/java/org/uberfire/client/views/pfly/listbar/PartListDropdown.java index 7e2288597f..0ed085916c 100644 --- a/uberfire-workbench/uberfire-workbench-client-views-patternfly/src/main/java/org/uberfire/client/views/pfly/listbar/PartListDropdown.java +++ b/uberfire-workbench/uberfire-workbench-client-views-patternfly/src/main/java/org/uberfire/client/views/pfly/listbar/PartListDropdown.java @@ -115,7 +115,7 @@ public void selectPart( final PartDefinition part ) { final Widget title = partTitles.get( part ); this.setText( title ); for ( final Map.Entry entry : partOptions.entrySet() ) { - if ( entry.getKey().equals( part ) ) { + if ( entry.getKey().asString().equals( part.asString() ) ) { entry.getValue().addStyleName( "uf-part-list-dropdown-selected" ); } else { entry.getValue().removeStyleName( "uf-part-list-dropdown-selected" ); diff --git a/uberfire-workbench/uberfire-workbench-client-views-patternfly/src/main/java/org/uberfire/client/views/pfly/toolbar/WorkbenchToolBarView.java b/uberfire-workbench/uberfire-workbench-client-views-patternfly/src/main/java/org/uberfire/client/views/pfly/toolbar/WorkbenchToolBarView.java index d832a13d2e..b7c37b83ef 100644 --- a/uberfire-workbench/uberfire-workbench-client-views-patternfly/src/main/java/org/uberfire/client/views/pfly/toolbar/WorkbenchToolBarView.java +++ b/uberfire-workbench/uberfire-workbench-client-views-patternfly/src/main/java/org/uberfire/client/views/pfly/toolbar/WorkbenchToolBarView.java @@ -15,6 +15,8 @@ */ package org.uberfire.client.views.pfly.toolbar; +import static org.uberfire.plugin.PluginUtil.*; + import java.util.HashMap; import java.util.Map; @@ -108,7 +110,7 @@ public void addToolBar( final ToolBar _toolBar ) { bgroup.getElement().getStyle().setPaddingLeft( 19, Style.Unit.PX ); } - for ( final ToolBarItem item : _toolBar.getItems() ) { + for ( final ToolBarItem item : ensureIterable ( _toolBar.getItems() ) ) { Button button = new Button(); button.setIcon( IconType.valueOf( ( (ToolBarTypeIcon) item.getIcon() ).getType().toString() ) ); button.setEnabled( item.isEnabled() ); diff --git a/uberfire-workbench/uberfire-workbench-client-views-patternfly/src/test/java/org/uberfire/client/views/pfly/mock/MockPlaceManager.java b/uberfire-workbench/uberfire-workbench-client-views-patternfly/src/test/java/org/uberfire/client/views/pfly/mock/MockPlaceManager.java index dff5383ee0..8246b84d10 100644 --- a/uberfire-workbench/uberfire-workbench-client-views-patternfly/src/test/java/org/uberfire/client/views/pfly/mock/MockPlaceManager.java +++ b/uberfire-workbench/uberfire-workbench-client-views-patternfly/src/test/java/org/uberfire/client/views/pfly/mock/MockPlaceManager.java @@ -165,4 +165,9 @@ public Collection getActivitiesForResourceType( final Resource throw new UnsupportedOperationException( "Not implemented." ); } + @Override + public Command getOpenCallback( PlaceRequest place ) { + throw new UnsupportedOperationException("Not implemented."); + } + } diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/menu/AuthFilterMenuVisitor.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/menu/AuthFilterMenuVisitor.java index fdc9b8415f..bf6a67a3b1 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/menu/AuthFilterMenuVisitor.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/menu/AuthFilterMenuVisitor.java @@ -31,6 +31,7 @@ import org.uberfire.workbench.model.menu.Menus; import static org.uberfire.commons.validation.PortablePreconditions.*; +import static org.uberfire.plugin.PluginUtil.*; /** * Wraps a menu visitor, filtering out menu items that a given user is not allowed to access. The wrapped visitor only @@ -120,13 +121,13 @@ public void visit( MenuItemPerspective menuItemPerspective ) { public boolean authorize( MenuItem item ) { List actions = item.getResourceActions(); if (actions != null && !actions.isEmpty()) { - for (ResourceActionRef ref : actions) { + for (ResourceActionRef ref : ensureIterable ( actions ) ) { if (!authzManager.authorize( ref.getResource(), ref.getAction(), user ) ) { return false; } } } - List permissions = item.getPermissions(); + List permissions = ensureIterable ( item.getPermissions() ); if (permissions != null && !permissions.isEmpty()) { for (String p : permissions) { if (!authzManager.authorize( p , user ) ) { @@ -141,7 +142,7 @@ public boolean authorize( MenuItem item ) { // For menu groups ensure at least one child item can be accessed if (item instanceof MenuGroup) { MenuGroup group = (MenuGroup) item; - for (MenuItem child : group.getItems()) { + for (MenuItem child : ensureIterable ( group.getItems() ) ) { if (authorize(child)) { return itemResult; } else { diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/AbstractActivity.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/AbstractActivity.java index c9a0b1db3f..a249d771b5 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/AbstractActivity.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/AbstractActivity.java @@ -15,12 +15,9 @@ */ package org.uberfire.client.mvp; -import java.util.List; - -import static org.uberfire.commons.validation.PortablePreconditions.*; +import static org.uberfire.commons.validation.PortablePreconditions.checkNotNull; import org.uberfire.mvp.PlaceRequest; -import org.uberfire.security.Resource; /** * Implementation of behaviour common to all activity types. @@ -100,4 +97,5 @@ public PlaceRequest getPlace() { public String toString() { return getClass().getName() + ( place == null ? " (not started)" : " for " + place ); } + } diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/AbstractSplashScreenActivity.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/AbstractSplashScreenActivity.java index 890136de85..b14f45fa85 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/AbstractSplashScreenActivity.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/AbstractSplashScreenActivity.java @@ -52,11 +52,6 @@ public AbstractSplashScreenActivity( final PlaceManager placeManager, this.splash = splash; } - @Override - public ResourceType getResourceType() { - return ActivityResourceType.SPLASH; - } - @PostConstruct private void initialize() { this.splashFilter = getFilter(); diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/AbstractWorkbenchActivity.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/AbstractWorkbenchActivity.java index a5f419252a..4de92a8ea4 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/AbstractWorkbenchActivity.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/AbstractWorkbenchActivity.java @@ -88,14 +88,4 @@ public String contextId() { return null; } - @Override - public Integer preferredHeight() { - return null; - } - - @Override - public Integer preferredWidth() { - return null; - } - } diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/AbstractWorkbenchEditorActivity.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/AbstractWorkbenchEditorActivity.java index 043799b9ed..56fc902ca4 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/AbstractWorkbenchEditorActivity.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/AbstractWorkbenchEditorActivity.java @@ -15,19 +15,18 @@ */ package org.uberfire.client.mvp; +import static org.uberfire.client.annotations.WorkbenchEditor.LockingStrategy.FRAMEWORK_PESSIMISTIC; + import javax.enterprise.inject.Instance; import javax.inject.Inject; import org.uberfire.backend.vfs.ObservablePath; +import org.uberfire.backend.vfs.Path; import org.uberfire.client.annotations.WorkbenchEditor; import org.uberfire.client.annotations.WorkbenchEditor.LockingStrategy; -import org.uberfire.workbench.model.ActivityResourceType; import org.uberfire.client.mvp.LockTarget.TitleProvider; import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.PathPlaceRequest; -import org.uberfire.security.ResourceType; - -import static org.uberfire.client.annotations.WorkbenchEditor.LockingStrategy.*; /** * Implementation of behaviour common to all workbench editor activities. Concrete implementations are typically not @@ -45,26 +44,34 @@ public AbstractWorkbenchEditorActivity( final PlaceManager placeManager ) { super( placeManager ); } - @Override - public ResourceType getResourceType() { - return ActivityResourceType.EDITOR; - } - /** * Overrides the default implementation by redirecting calls that are {@link PathPlaceRequest} instances to * {@link #onStartup(ObservablePath, PlaceRequest)}. Non-path place requests are handed up to the super impl. */ @Override public final void onStartup( final PlaceRequest place ) { - if ( place instanceof PathPlaceRequest ) { - onStartup( ( (PathPlaceRequest) place ).getPath(), - place ); - } else { - // XXX should throw an exception here instead? can an editor be launched without a path? + final Path path = place.getPath(); + if ( path != null ) { + if ( path instanceof ObservablePath ) { + onStartup( (ObservablePath) path, + place ); + } else if ( this.isDynamic() ) { + onStartup( path, + place ); + } + } + else { super.onStartup( place ); } } + + void onStartup( final Path path, + final PlaceRequest place ) { + onStartup( new PathPlaceRequest( path ).getPath(), + place ); + } + @Override public void onStartup( final ObservablePath path, final PlaceRequest place ) { diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/AbstractWorkbenchPerspectiveActivity.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/AbstractWorkbenchPerspectiveActivity.java index ffdd86ff57..eaac8aa232 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/AbstractWorkbenchPerspectiveActivity.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/AbstractWorkbenchPerspectiveActivity.java @@ -16,8 +16,8 @@ package org.uberfire.client.mvp; import org.uberfire.client.annotations.WorkbenchPerspective; -import org.uberfire.workbench.model.ActivityResourceType; import org.uberfire.security.ResourceType; +import org.uberfire.workbench.model.ActivityResourceType; import org.uberfire.workbench.model.PerspectiveDefinition; import org.uberfire.workbench.model.menu.Menus; import org.uberfire.workbench.model.toolbar.ToolBar; @@ -59,4 +59,5 @@ public Menus getMenus() { public ToolBar getToolBar() { return null; } + } diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/Activity.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/Activity.java index 4f2b9777e3..8a42809535 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/Activity.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/Activity.java @@ -20,7 +20,9 @@ import org.uberfire.client.annotations.WorkbenchScreen; import org.uberfire.mvp.PlaceRequest; import org.uberfire.security.authz.RuntimeFeatureResource; -import org.uberfire.security.authz.RuntimeResource; + +import jsinterop.annotations.JsMethod; +import jsinterop.annotations.JsType; /** * Common top-level interface for all Workbench Activity classes. No concrete class implements this interface directly; @@ -59,6 +61,7 @@ * @see PlaceManager * @see ActivityManager */ +@JsType public interface Activity extends RuntimeFeatureResource { /** @@ -68,6 +71,7 @@ public interface Activity extends RuntimeFeatureResource { * @param place * The place that resolved to this activity */ + @JsMethod(name = "onStartupPlace") void onStartup( final PlaceRequest place ); /** @@ -93,4 +97,32 @@ public interface Activity extends RuntimeFeatureResource { * state. */ PlaceRequest getPlace(); + + /** + * Returns whether or not this activity should be executed by default (on startup). + * + * @return true, if this activity should be executed by default, otherwise false. + */ + default boolean isDefault() { + return false; + } + + /** + * Returns whether or not this activity is marked as dynamic (provided by external scripts). + * + * @return true if this activity is dynamic, otherwise false. + */ + default boolean isDynamic() { + return false; + } + + /** + * Returns the name of this activity, defaulting to {@link #getIdentifier()}. + * + * @return the activity's name + */ + default String getName() { + return getIdentifier(); + } + } diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/ActivityBeansCache.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/ActivityBeansCache.java index 69c7f499cf..4310e0c58b 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/ActivityBeansCache.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/ActivityBeansCache.java @@ -32,6 +32,7 @@ import javax.inject.Inject; import javax.inject.Named; +import org.jboss.errai.ioc.client.api.EnabledByProperty; import org.jboss.errai.ioc.client.api.EntryPoint; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; @@ -46,6 +47,7 @@ * */ @EntryPoint +@EnabledByProperty(value = "uberfire.plugin.mode.active", negated = true) public class ActivityBeansCache { @Inject @@ -80,14 +82,14 @@ void init() { final String id = activityBean.getName(); - validateUniqueness( activityBean, id ); + validateUniqueness( id ); activitiesById.put( id, activityBean ); if ( isSplashScreen( activityBean.getQualifiers() ) ) { splashActivities.add( (SplashScreenActivity) activityBean.getInstance() ); } else { - final Pair>> metaInfo = generateActivityMetaInfo( activityBean ); + final Pair> metaInfo = generateActivityMetaInfo( activityBean ); if ( metaInfo != null ) { getResourceActivities().add( new ActivityAndMetaInfo( activityBean, metaInfo.getK1(), metaInfo.getK2() ) ); } @@ -148,16 +150,15 @@ public void removeActivity( String id ) { public void addNewScreenActivity( final SyncBeanDef activityBean ) { final String id = activityBean.getName(); - validateUniqueness( activityBean, id ); + validateUniqueness( id ); activitiesById.put( id, activityBean ); newWorkbenchScreenEventEvent.fire( new NewWorkbenchScreenEvent( id ) ); } - private void validateUniqueness( final SyncBeanDef activityBean, - final String id ) { + private void validateUniqueness( final String id ) { if ( activitiesById.keySet().contains( id ) ) { - throw new RuntimeException( "Conflict detected. Activity Id already exists. " + activityBean.getBeanClass().toString() + " with id " + activityBean.getName() ); + throw new RuntimeException( "Conflict detected: Activity already exists with id " + id ); } } @@ -165,7 +166,7 @@ private void validateUniqueness( final SyncBeanDef activityBean, public void addNewPerspectiveActivity( final SyncBeanDef activityBean ) { final String id = activityBean.getName(); - validateUniqueness( activityBean, id ); + validateUniqueness( id ); activitiesById.put( id, activityBean ); newPerspectiveEventEvent.fire( new NewPerspectiveEvent( id ) ); @@ -176,17 +177,17 @@ public void addNewEditorActivity( final SyncBeanDef activityBean, Class resourceTypeClass ) { final String id = activityBean.getName(); - validateUniqueness( activityBean, id ); + validateUniqueness( id ); - final List> resourceTypes = new ArrayList>(); - resourceTypes.add( resourceTypeClass ); + final List resourceTypes = new ArrayList(); + resourceTypes.add( resourceTypeClass.getName() ); resourceActivities.add( new ActivityAndMetaInfo( activityBean, 0, resourceTypes ) ); } public void addNewSplashScreenActivity( final SyncBeanDef activityBean ) { final String id = activityBean.getName(); - validateUniqueness( activityBean, id ); + validateUniqueness( id ); activitiesById.put( id, activityBean ); splashActivities.add( (SplashScreenActivity) activityBean.getInstance() ); @@ -232,7 +233,7 @@ public SyncBeanDef getActivity( final Path path ) { throw new EditorResourceTypeNotFound(); } - Pair>> generateActivityMetaInfo( SyncBeanDef activityBean ) { + Pair> generateActivityMetaInfo( SyncBeanDef activityBean ) { return ActivityMetaInfo.generate( activityBean ); } @@ -246,15 +247,22 @@ class ActivityAndMetaInfo { private final int priority; private final ClientResourceType[] resourceTypes; + @SuppressWarnings("rawtypes") ActivityAndMetaInfo( final SyncBeanDef activityBean, final int priority, - final List> resourceTypes ) { + final List resourceTypes ) { this.activityBean = activityBean; this.priority = priority; this.resourceTypes = new ClientResourceType[ resourceTypes.size() ]; for ( int i = 0; i < resourceTypes.size(); i++ ) { - this.resourceTypes[ i ] = iocManager.lookupBean( resourceTypes.get( i ) ).getInstance(); + final String resourceTypeFqcn = resourceTypes.get( i ); + final Collection resourceTypeBeans = iocManager.lookupBeans( resourceTypeFqcn ); + if (resourceTypeBeans.isEmpty()) { + throw new RuntimeException("ClientResourceType " + resourceTypeFqcn + " not found"); + } + + this.resourceTypes[ i ] = (ClientResourceType) resourceTypeBeans.iterator().next().getInstance(); } } diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/ActivityManagerImpl.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/ActivityManagerImpl.java index 591026a11d..c4d8c46332 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/ActivityManagerImpl.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/ActivityManagerImpl.java @@ -32,6 +32,7 @@ import javax.enterprise.context.Dependent; import javax.inject.Inject; +import org.jboss.errai.ioc.client.api.EnabledByProperty; import org.jboss.errai.ioc.client.container.IOCBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; @@ -39,10 +40,13 @@ import org.uberfire.backend.vfs.Path; import org.uberfire.client.mvp.ActivityLifecycleError.LifecyclePhase; import org.uberfire.mvp.PlaceRequest; +import org.uberfire.mvp.impl.ExternalPathPlaceRequest; import org.uberfire.mvp.impl.PathPlaceRequest; import org.uberfire.security.authz.AuthorizationManager; +import org.uberfire.workbench.model.ActivityResourceType; @ApplicationScoped +@EnabledByProperty(value = "uberfire.plugin.mode.active", negated = true) public class ActivityManagerImpl implements ActivityManager { @Inject @@ -264,7 +268,12 @@ private T startIfNecessary( T activity, try { if ( !startedActivities.containsKey( activity ) ) { startedActivities.put( activity, place ); - activity.onStartup( place ); + if (activity.isDynamic() && place instanceof PathPlaceRequest ) { + activity.onStartup( ExternalPathPlaceRequest.create( (PathPlaceRequest) place ) ); + } + else { + activity.onStartup( place ); + } } return activity; } catch ( Exception ex ) { diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/ActivityMetaInfo.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/ActivityMetaInfo.java index ebc2bf8d0b..5b194cbcf0 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/ActivityMetaInfo.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/ActivityMetaInfo.java @@ -18,9 +18,11 @@ import java.lang.annotation.Annotation; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Set; +import org.jboss.errai.ioc.client.container.DynamicAnnotation; import org.jboss.errai.ioc.client.container.IOCBeanDef; import org.uberfire.client.workbench.annotations.AssociatedResources; import org.uberfire.client.workbench.annotations.Priority; @@ -29,37 +31,59 @@ public class ActivityMetaInfo { - static Pair>> generate(final IOCBeanDef beanDefinition){ + static Pair> generate(final IOCBeanDef beanDefinition){ AssociatedResources associatedResources = null; + DynamicAnnotation dynAssociatedResources = null; + Priority priority = null; + DynamicAnnotation dynPriority = null; final Set annotations = beanDefinition.getQualifiers(); + final boolean dynamic = beanDefinition.isDynamic(); + for ( Annotation a : annotations ) { - if ( a instanceof AssociatedResources ) { + final DynamicAnnotation da = (dynamic) ? (DynamicAnnotation) a : null; + if ( a instanceof AssociatedResources ) { associatedResources = (AssociatedResources) a; - continue; } - if ( a instanceof Priority ) { + else if (da != null && AssociatedResources.class.getName().equals( da.getName() ) ) { + dynAssociatedResources = da; + } + else if ( a instanceof Priority) { priority = (Priority) a; - continue; + } + else if (da != null && Priority.class.getName().equals( da.getName() ) ) { + dynPriority = da; } } - if ( associatedResources == null ) { + if ( associatedResources == null && dynAssociatedResources == null ) { return null; } final int priorityValue; - if ( priority == null ) { + if ( priority == null && dynPriority == null ) { priorityValue = 0; } else { - priorityValue = priority.value(); + if (dynamic) { + priorityValue = Integer.valueOf( dynPriority.getMember( "value" ) ); + } + else { + priorityValue = priority.value(); + } } - final List> types = new ArrayList>(); - for ( Class type : associatedResources.value() ) { - types.add( type ); + final List types = new ArrayList(); + if (dynamic) { + String resourceTypes = dynAssociatedResources.getMember( "value" ); + resourceTypes = resourceTypes.substring( 1, resourceTypes.length() - 1 ); + types.addAll( Arrays.asList( resourceTypes.split( "," ) ) ); + } + else { + for ( Class type : associatedResources.value() ) { + types.add( type.getName() ); + } } return Pair.newPair( priorityValue, types ); diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/LockManager.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/LockManager.java index f08e02cac5..08abd992c2 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/LockManager.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/LockManager.java @@ -18,10 +18,13 @@ import org.uberfire.client.workbench.events.ChangeTitleWidgetEvent; +import jsinterop.annotations.JsType; + /** * Provides functionality to lock a file or directory, associated with a widget * (i.e a workbench screen or editor). */ +@JsType public interface LockManager { /** diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/PerspectiveActivity.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/PerspectiveActivity.java index c8b03becfd..31b76568a6 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/PerspectiveActivity.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/PerspectiveActivity.java @@ -20,6 +20,9 @@ import org.uberfire.workbench.model.menu.Menus; import org.uberfire.workbench.model.toolbar.ToolBar; +import jsinterop.annotations.JsType; + +@JsType public interface PerspectiveActivity extends ContextSensitiveActivity { /** @@ -32,6 +35,11 @@ public interface PerspectiveActivity extends ContextSensitiveActivity { * @see WorkbenchServicesProxy#loadPerspective(String, org.uberfire.mvp.ParameterizedCommand) */ PerspectiveDefinition getDefaultPerspectiveLayout(); + + @Override + default String getName() { + return getDefaultPerspectiveLayout().getName(); + } /** * Returns true if this perspective should be displayed automatically when the application starts. Each application diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/PerspectiveManagerImpl.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/PerspectiveManagerImpl.java index f9773ae87e..26c2c47fdd 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/PerspectiveManagerImpl.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/PerspectiveManagerImpl.java @@ -16,7 +16,11 @@ package org.uberfire.client.mvp; +import static org.uberfire.commons.validation.PortablePreconditions.checkNotNull; +import static org.uberfire.plugin.PluginUtil.*; + import java.util.Set; + import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Event; import javax.inject.Inject; @@ -30,8 +34,6 @@ import org.uberfire.workbench.model.PanelDefinition; import org.uberfire.workbench.model.PerspectiveDefinition; -import static org.uberfire.commons.validation.PortablePreconditions.*; - @ApplicationScoped public class PerspectiveManagerImpl implements PerspectiveManager { @@ -164,14 +166,14 @@ public void execute( PerspectiveDefinition perspectiveDef ) { } private void tearDownChildPanelsRecursively( final PanelDefinition panel ) { - for ( PanelDefinition child : panel.getChildren() ) { + for ( PanelDefinition child : ensureIterable( panel.getChildren() ) ) { tearDownChildPanelsRecursively( child ); panelManager.removeWorkbenchPanel( child ); } } private void setupPanelRecursively( final PanelDefinition panel ) { - for ( PanelDefinition child : panel.getChildren() ) { + for ( PanelDefinition child : ensureIterable( panel.getChildren() ) ) { final PanelDefinition target = panelManager.addWorkbenchPanel( panel, child, child.getPosition() ); diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/PlaceManager.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/PlaceManager.java index ed73ee7415..c06e753b67 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/PlaceManager.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/PlaceManager.java @@ -16,9 +16,10 @@ package org.uberfire.client.mvp; +import static org.uberfire.commons.validation.PortablePreconditions.checkNotNull; + import java.util.Collection; -import com.google.gwt.user.client.ui.HasWidgets; import org.uberfire.backend.vfs.Path; import org.uberfire.client.annotations.WorkbenchEditor; import org.uberfire.client.annotations.WorkbenchPerspective; @@ -32,35 +33,51 @@ import org.uberfire.workbench.model.PartDefinition; import org.uberfire.workbench.type.ResourceTypeDefinition; +import com.google.gwt.user.client.ui.HasWidgets; + +import jsinterop.annotations.JsIgnore; +import jsinterop.annotations.JsMethod; +import jsinterop.annotations.JsType; + /** * A Workbench-centric abstraction over the browser's history mechanism. Allows the application to initiate navigation * to any displayable thing: a {@link WorkbenchPerspective}, a {@link WorkbenchScreen}, a {@link WorkbenchPopup}, a * {@link WorkbenchEditor}, a {@link WorkbenchPart} within a screen or editor, or the editor associated with a VFS file * located at a particular {@link Path}. */ +@JsType public interface PlaceManager { - + + @JsMethod(name="goToId") void goTo( final String identifier ); + @JsMethod(name="goToPlace") void goTo( final PlaceRequest place ); + @JsMethod(name="goToPath") void goTo( final Path path ); + @JsMethod(name="goToPathAndPlace") void goTo( final Path path, final PlaceRequest place ); + @JsMethod(name="goToPartWithPanel") void goTo( final PartDefinition part, final PanelDefinition panel ); + @JsMethod(name="goToIdWithPanel") void goTo( final String identifier, final PanelDefinition panel ); + @JsMethod(name="goToPlaceWithPanel") void goTo( final PlaceRequest place, final PanelDefinition panel ); + @JsMethod(name="goToPathWithPanel") void goTo( final Path path, final PanelDefinition panel ); + @JsMethod(name="goToPathAndPlaceWithPanel") void goTo( final Path path, final PlaceRequest place, final PanelDefinition panel ); @@ -84,6 +101,7 @@ void goTo( final Path path, * be accomplished through direct use of CSS, or through the * {@link Layouts#setToFillParent(com.google.gwt.user.client.ui.Widget)} call. */ + @JsIgnore void goTo( final PlaceRequest place, final HasWidgets addTo ); @@ -99,19 +117,36 @@ void goTo( final PlaceRequest place, */ Activity getActivity( final PlaceRequest place ); + @JsMethod(name="getStatusById") PlaceStatus getStatus( final String id ); + @JsMethod(name="getStatusByPlaceRequest") PlaceStatus getStatus( final PlaceRequest place ); - void closePlace( final String id ); + default void executeOnOpenCallback( final PlaceRequest place ) { + checkNotNull( "place", + place ); + + final Command callback = getOpenCallback( place ); + if ( callback != null ) { + callback.execute(); + } + } - void closePlace( final PlaceRequest place ); + public Command getOpenCallback( PlaceRequest place ); + @JsMethod(name = "closePlaceById") + void closePlace( final String id ); + + void closePlace( final PlaceRequest placeToClose ); + void tryClosePlace( final PlaceRequest placeToClose, final Command onAfterClose ); + @JsMethod(name="forceCloseById") void forceClosePlace( final String id ); + @JsMethod(name="forceCloseByPlaceRequest") void forceClosePlace( final PlaceRequest place ); void closeAllPlaces(); @@ -121,8 +156,7 @@ void registerOnOpenCallback( final PlaceRequest place, void unregisterOnOpenCallback( final PlaceRequest place ); - void executeOnOpenCallback( final PlaceRequest place ); - + @JsIgnore Collection getActiveSplashScreens(); /** @@ -133,6 +167,7 @@ void registerOnOpenCallback( final PlaceRequest place, * @return an unmodifiable collection of PlaceRequests for the currently open WorkbenchEditorActivities that * can handle the ResourceTypeDefinition. Returns an empty collection if no match was found. */ + @JsIgnore Collection getActivitiesForResourceType(final ResourceTypeDefinition type); } diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/PlaceManagerImpl.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/PlaceManagerImpl.java index 1284422dcd..0a1a8c94ed 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/PlaceManagerImpl.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/PlaceManagerImpl.java @@ -15,6 +15,10 @@ */ package org.uberfire.client.mvp; +import static java.util.Collections.unmodifiableCollection; +import static org.uberfire.commons.validation.PortablePreconditions.checkNotNull; +import static org.uberfire.plugin.PluginUtil.*; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -22,6 +26,8 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.function.Supplier; + import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Event; @@ -29,9 +35,10 @@ import javax.enterprise.inject.Produces; import javax.inject.Inject; -import com.google.gwt.user.client.ui.HasWidgets; -import com.google.web.bindery.event.shared.EventBus; -import com.google.web.bindery.event.shared.SimpleEventBus; +import org.jboss.errai.common.client.ui.ElementWrapperWidget; +import org.jboss.errai.ioc.client.api.EnabledByProperty; +import org.jboss.errai.ioc.client.api.SharedSingleton; +import org.uberfire.backend.vfs.ObservablePath; import org.uberfire.backend.vfs.Path; import org.uberfire.client.menu.SplashScreenMenuPresenter; import org.uberfire.client.mvp.ActivityLifecycleError.LifecyclePhase; @@ -52,6 +59,7 @@ import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.mvp.impl.ForcedPlaceRequest; import org.uberfire.mvp.impl.PathPlaceRequest; +import org.uberfire.workbench.model.ActivityResourceType; import org.uberfire.workbench.model.PanelDefinition; import org.uberfire.workbench.model.PartDefinition; import org.uberfire.workbench.model.PerspectiveDefinition; @@ -59,10 +67,16 @@ import org.uberfire.workbench.model.impl.PartDefinitionImpl; import org.uberfire.workbench.type.ResourceTypeDefinition; -import static java.util.Collections.*; -import static org.uberfire.commons.validation.PortablePreconditions.*; +import com.google.gwt.dom.client.Element; +import com.google.gwt.user.client.ui.HasWidgets; +import com.google.gwt.user.client.ui.IsWidget; +import com.google.web.bindery.event.shared.EventBus; +import com.google.web.bindery.event.shared.SimpleEventBus; + +import jsinterop.annotations.JsMethod; -@ApplicationScoped +@SharedSingleton +@EnabledByProperty(value = "uberfire.plugin.mode.active", negated = true) public class PlaceManagerImpl implements PlaceManager { @@ -209,7 +223,7 @@ private void goTo( final PlaceRequest place, if ( resolved.getActivity() != null ) { final Activity activity = resolved.getActivity(); - if ( activity instanceof WorkbenchActivity ) { + if ( activity.isType( ActivityResourceType.SCREEN.name() ) || activity.isType( ActivityResourceType.EDITOR.name() ) ) { final WorkbenchActivity workbenchActivity = (WorkbenchActivity) activity; // check if we need to open the owning perspective before launching this screen/editor @@ -229,12 +243,12 @@ public void execute() { panel ); doWhenFinished.execute(); - } else if ( activity instanceof PopupActivity ) { + } else if ( activity.isType( ActivityResourceType.POPUP.name() ) ) { launchPopupActivity( resolved.getPlaceRequest(), (PopupActivity) activity ); doWhenFinished.execute(); - } else if ( activity instanceof PerspectiveActivity ) { + } else if ( activity.isType( ActivityResourceType.PERSPECTIVE.name() ) ) { launchPerspectiveActivity( place, (PerspectiveActivity) activity, doWhenFinished ); } } else { @@ -246,7 +260,7 @@ private boolean closePlaces( final Collection placeRequests ) { boolean result = true; for ( final PlaceRequest placeRequest : placeRequests ) { final Activity activity = existingWorkbenchActivities.get( placeRequest ); - if ( activity instanceof WorkbenchActivity ) { + if ( activity.isType( ActivityResourceType.SCREEN.name() ) || activity.isType( ActivityResourceType.EDITOR.name() ) ) { if ( ( (WorkbenchActivity) activity ).onMayClose() ) { onMayCloseList.put( placeRequest, activity ); } else { @@ -327,10 +341,16 @@ private ResolvedRequest resolveExistingParts( final PlaceRequest place ) { } if ( place instanceof PathPlaceRequest ) { + final ObservablePath path = ( (PathPlaceRequest) place ).getPath(); + for ( final Map.Entry entry : visibleWorkbenchParts.entrySet() ) { - if ( entry.getKey() instanceof PathPlaceRequest && - ( (PathPlaceRequest) entry.getKey() ).getPath().compareTo( ( (PathPlaceRequest) place ).getPath() ) == 0 ) { - return new ResolvedRequest( getActivity( entry.getKey() ), entry.getKey() ); + final PlaceRequest pr = entry.getKey(); + if ( pr instanceof PathPlaceRequest ) { + final Path visiblePath = ( (PathPlaceRequest) pr ).getPath(); + final String visiblePathURI = visiblePath.toURI(); + if ( (visiblePathURI != null && visiblePathURI.compareTo( path.toURI() ) == 0) || visiblePath.compareTo( path ) == 0) { + return new ResolvedRequest( getActivity( pr ), pr ); + } } } } @@ -350,7 +370,7 @@ public void goTo( final PartDefinition part, if ( resolved.getActivity() != null ) { final Activity activity = resolved.getActivity(); - if ( activity instanceof WorkbenchActivity ) { + if ( activity.isType( ActivityResourceType.EDITOR.name() ) || activity.isType( ActivityResourceType.SCREEN.name() )) { final WorkbenchActivity workbenchActivity = (WorkbenchActivity) activity; launchWorkbenchActivityInPanel( place, workbenchActivity, @@ -368,8 +388,8 @@ private PlaceRequest getPlace( final Path path, final PlaceRequest placeRequest ) { final PlaceRequest request = new PathPlaceRequest( path ); - for ( final Map.Entry entry : placeRequest.getParameters().entrySet() ) { - request.addParameter( entry.getKey(), entry.getValue() ); + for ( final String name : ensureIterable( placeRequest.getParameterNames() ) ) { + request.addParameter( name, placeRequest.getParameters().get( name ) ); } return request; @@ -398,11 +418,13 @@ public PlaceStatus getStatus( final PlaceRequest place ) { return resolveExistingParts( place ) != null ? PlaceStatus.OPEN : PlaceStatus.CLOSE; } + @JsMethod @Override public void closePlace( final String id ) { closePlace( new DefaultPlaceRequest( id ) ); } + @JsMethod @Override public void closePlace( final PlaceRequest placeToClose ) { if ( placeToClose == null ) { @@ -466,15 +488,6 @@ public void unregisterOnOpenCallback( final PlaceRequest place ) { this.onOpenCallbacks.remove( place ); } - @Override - public void executeOnOpenCallback( final PlaceRequest place ) { - checkNotNull( "place", place ); - final Command callback = this.onOpenCallbacks.get( place ); - if ( callback != null ) { - callback.execute(); - } - } - /** * Finds and opens the splash screen for the given place, if such a splash screen exists. The splash screen might * not actually display; each splash screen keeps track of its own preference setting for whether or not the user @@ -611,7 +624,17 @@ private void launchWorkbenchActivityInPanel( final PlaceRequest place, visibleWorkbenchParts.put( place, part ); getPlaceHistoryHandler().onPlaceChange( place ); - UIPart uiPart = new UIPart( activity.getTitle(), activity.getTitleDecoration(), activity.getWidget() ); + final IsWidget titleDecoration = maybeWrapExternalWidget( activity, + () -> activity.getTitleDecorationElement(), + () -> activity.getTitleDecoration() ); + + final IsWidget widget = maybeWrapExternalWidget( activity, + () -> activity.getWidgetElement(), + () -> activity.getWidget() ); + + final UIPart uiPart = new UIPart( activity.getTitle(), + titleDecoration, + widget ); panelManager.addWorkbenchPart( place, part, @@ -619,8 +642,8 @@ private void launchWorkbenchActivityInPanel( final PlaceRequest place, activity.getMenus(), uiPart, activity.contextId(), - panel.getWidth(), - panel.getHeight() ); + toInteger( panel.getWidthAsInt() ), + toInteger( panel.getHeightAsInt() ) ); addSplashScreenFor( place ); try { @@ -630,6 +653,18 @@ private void launchWorkbenchActivityInPanel( final PlaceRequest place, closePlace( place ); } } + + private IsWidget maybeWrapExternalWidget( WorkbenchActivity activity, + Supplier element, + Supplier widget ) { + + if ( activity.isDynamic() ) { + final Element e = element.get(); + return (e == null) ? null : ElementWrapperWidget.getWidget( e ); + } + + return widget.get(); + } private void launchPopupActivity( final PlaceRequest place, final PopupActivity activity ) { @@ -750,12 +785,12 @@ private void switchToPerspective( final PlaceRequest place, * process. */ private void openPartsRecursively( PanelDefinition panel ) { - for ( PartDefinition part : new ArrayList( panel.getParts() ) ) { + for ( PartDefinition part : ensureIterable ( panel.getParts() ) ) { final PlaceRequest place = part.getPlace().clone(); part.setPlace( place ); goTo( part, panel ); } - for ( PanelDefinition child : panel.getChildren() ) { + for ( PanelDefinition child : ensureIterable ( panel.getChildren() ) ) { openPartsRecursively( child ); } } @@ -775,7 +810,7 @@ private void closePlace( final PlaceRequest place, closeSplashScreen( place ); activePopups.remove( place.getIdentifier() ); - if ( activity instanceof WorkbenchActivity ) { + if ( activity.isType( ActivityResourceType.SCREEN.name() ) || activity.isType( ActivityResourceType.EDITOR.name() ) ) { WorkbenchActivity activity1 = (WorkbenchActivity) activity; if ( force || onMayCloseList.containsKey( place ) || activity1.onMayClose() ) { onMayCloseList.remove( place ); @@ -787,7 +822,7 @@ private void closePlace( final PlaceRequest place, } else { return; } - } else if ( activity instanceof PopupActivity ) { + } else if ( activity.isType( ActivityResourceType.POPUP.name() ) ) { PopupActivity activity1 = (PopupActivity) activity; if ( force || activity1.onMayClose() ) { try { @@ -907,4 +942,10 @@ public String toString() { return "{activity=" + activity + ", placeRequest=" + placeRequest + "}"; } } + + @Override + public Command getOpenCallback( PlaceRequest place ) { + return this.onOpenCallbacks.get( place ); + } + } diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/PlaceStatus.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/PlaceStatus.java index f2665991cc..1adfe17f81 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/PlaceStatus.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/PlaceStatus.java @@ -16,6 +16,9 @@ package org.uberfire.client.mvp; +import jsinterop.annotations.JsType; + +@JsType public enum PlaceStatus { OPEN, CLOSE } diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/PluginActivityManagerImpl.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/PluginActivityManagerImpl.java new file mode 100644 index 0000000000..6d09861023 --- /dev/null +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/PluginActivityManagerImpl.java @@ -0,0 +1,112 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS 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.mvp; + +import java.util.Set; + +import javax.enterprise.context.ApplicationScoped; + +import org.jboss.errai.ioc.client.api.EnabledByProperty; +import org.uberfire.mvp.PlaceRequest; + +/** + * This {@link ActivityManager} implementation is active for plugins only, to + * satisfy compile-time dependencies (of other components on the plugin's + * classpath that require an activity manager). Plugins don't get access to the + * main application's {@link ActivityManager} as it would allow them to control + * all activities of the application, not just their own. + */ +@ApplicationScoped +@EnabledByProperty(value = "uberfire.plugin.mode.active") +public class PluginActivityManagerImpl implements ActivityManager { + + private void fail() { + // Plugins should not be able to interact with the activity manager. + throw new RuntimeException( "Invalid use of ActivityManager in plugin." ); + } + + @Override + public Set getActivities( final Class clazz ) { + fail(); + return null; + } + + @Override + public SplashScreenActivity getSplashScreenInterceptor( final PlaceRequest placeRequest ) { + fail(); + return null; + } + + @Override + public Set getActivities( final PlaceRequest placeRequest ) { + fail(); + return null; + } + + @Override + public boolean containsActivity( final PlaceRequest placeRequest ) { + fail(); + return false; + } + + @Override + public Activity getActivity( final PlaceRequest placeRequest ) { + fail(); + return null; + } + + @Override + public T getActivity( final Class clazz, + final PlaceRequest placeRequest ) { + fail(); + return null; + } + + @Override + public void destroyActivity( final Activity activity ) { + fail(); + } + + @Override + public boolean isStarted( final Activity activity ) { + fail(); + return false; + } + + @Override + public Set getActivities( PlaceRequest placeRequest, + boolean secure ) { + fail(); + return null; + } + + @Override + public Activity getActivity( PlaceRequest placeRequest, + boolean secure ) { + fail(); + return null; + } + + @Override + public T getActivity( Class clazz, + PlaceRequest placeRequest, + boolean secure ) { + fail(); + return null; + } + +} diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/PluginPlaceManagerImpl.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/PluginPlaceManagerImpl.java new file mode 100644 index 0000000000..a42eba8678 --- /dev/null +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/PluginPlaceManagerImpl.java @@ -0,0 +1,221 @@ +/* + * Copyright 2015 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS 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.mvp; + +import java.util.Collection; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; + +import org.jboss.errai.ioc.client.api.EnabledByProperty; +import org.jboss.errai.ioc.client.api.Shared; +import org.jboss.errai.ioc.client.api.SharedSingleton; +import org.uberfire.backend.vfs.ObservablePath; +import org.uberfire.backend.vfs.Path; +import org.uberfire.client.workbench.WorkbenchLayout; +import org.uberfire.client.workbench.widgets.menu.WorkbenchMenuBar; +import org.uberfire.mvp.Command; +import org.uberfire.mvp.PlaceRequest; +import org.uberfire.mvp.impl.PathPlaceRequest; +import org.uberfire.workbench.model.PanelDefinition; +import org.uberfire.workbench.model.PartDefinition; +import org.uberfire.workbench.type.ResourceTypeDefinition; + +import com.google.gwt.user.client.ui.HasWidgets; + +/** + * This {@link PlaceManager} implementation is active for plugins only, to + * satisfy compile-time dependencies (of other components on the plugin's + * classpath that require a place manager). It is not used at runtime as plugins + * use the {@link SharedSingleton} {@link PlaceManager} provided by the main + * application. Plugins get access to a fully functional {@link PlaceManager} + * using @{@link Inject} @{@link Shared} {@link ShareablePlaceManager}. + */ +@ApplicationScoped +@EnabledByProperty(value = "uberfire.plugin.mode.active") +public class PluginPlaceManagerImpl implements PlaceManager { + + // Avoid pruning by aggressive reachability analysis in Errai + @SuppressWarnings("unused") + @Inject + private WorkbenchLayout workbenchLayout; + + // Avoid pruning by aggressive reachability analysis in Errai + @SuppressWarnings("unused") + @Inject + private WorkbenchMenuBar menubar; + + // Avoid pruning by aggressive reachability analysis in Errai + @SuppressWarnings("unused") + @Inject + private ObservablePath path; + + // Avoid pruning by aggressive reachability analysis in Errai + @SuppressWarnings("unused") + @Inject + private LockManager lockManager; + + private void fail() { + throw new RuntimeException( "Invalid use of standard PlaceManager in plugin. " + + "Use @Inject @" + Shared.class.getName() + " " + + PlaceManager.class.getName() + " instead!" ); + } + + @Override + public void goTo( final String identifier, + final PanelDefinition panel ) { + + fail(); + } + + @Override + public void goTo( final String identifier ) { + + fail(); + } + + @Override + public void goTo( PlaceRequest place ) { + + fail(); + } + + @Override + public void goTo( final Path path, + final PanelDefinition panel ) { + + fail(); + + } + + @Override + public void goTo( final Path path ) { + fail(); + } + + @Override + public void goTo( final Path path, + final PlaceRequest placeRequest, + final PanelDefinition panel ) { + fail(); + } + + @Override + public void goTo( final Path path, + final PlaceRequest placeRequest ) { + fail(); + } + + @Override + public void goTo( final PlaceRequest place, + final PanelDefinition panel ) { + fail(); + } + + @Override + public void goTo( PlaceRequest place, + HasWidgets addTo ) { + fail(); + } + + @Override + public void goTo( final PartDefinition part, + final PanelDefinition panel ) { + fail(); + } + + @Override + public Activity getActivity( final PlaceRequest place ) { + fail(); + + return null; + } + + @Override + public PlaceStatus getStatus( String id ) { + fail(); + + return null; + } + + @Override + public PlaceStatus getStatus( final PlaceRequest place ) { + fail(); + + return null; + } + + @Override + public void closePlace( final String id ) { + fail(); + } + + @Override + public void closePlace( final PlaceRequest placeToClose ) { + fail(); + } + + @Override + public void tryClosePlace( final PlaceRequest placeToClose, + final Command onAfterClose ) { + fail(); + } + + @Override + public void forceClosePlace( final String id ) { + fail(); + } + + @Override + public void forceClosePlace( final PlaceRequest placeToClose ) { + fail(); + } + + @Override + public void closeAllPlaces() { + fail(); + } + + @Override + public void registerOnOpenCallback( final PlaceRequest place, + final Command command ) { + fail(); + } + + @Override + public void unregisterOnOpenCallback( final PlaceRequest place ) { + fail(); + } + + @Override + public Collection getActiveSplashScreens() { + fail(); + return null; + } + + @Override + public Command getOpenCallback( PlaceRequest place ) { + fail(); + return null; + } + + @Override + public Collection getActivitiesForResourceType( ResourceTypeDefinition type ) { + fail(); + return null; + } + +} diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/SplashScreenActivity.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/SplashScreenActivity.java index 926f67ea2f..28fb2a10a4 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/SplashScreenActivity.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/SplashScreenActivity.java @@ -17,6 +17,8 @@ import com.google.gwt.user.client.ui.IsWidget; import org.uberfire.mvp.PlaceRequest; +import org.uberfire.security.ResourceType; +import org.uberfire.workbench.model.ActivityResourceType; import org.uberfire.workbench.model.SplashScreenFilter; public interface SplashScreenActivity extends Activity { @@ -38,5 +40,10 @@ public interface SplashScreenActivity extends Activity { Boolean intercept( final PlaceRequest intercepted ); boolean isEnabled(); - + + @Override + default ResourceType getResourceType() { + return ActivityResourceType.SPLASH; + } + } diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/WorkbenchActivity.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/WorkbenchActivity.java index 8107f1e5b7..24e59c28ca 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/WorkbenchActivity.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/WorkbenchActivity.java @@ -24,8 +24,12 @@ import org.uberfire.workbench.model.menu.Menus; import org.uberfire.workbench.model.toolbar.ToolBar; +import com.google.gwt.dom.client.Element; import com.google.gwt.user.client.ui.IsWidget; +import jsinterop.annotations.JsIgnore; +import jsinterop.annotations.JsType; + /** * WorkbenchActivity and its subinterfaces define the interface between UberFire framework behaviour and * application-defined behaviour. @@ -45,6 +49,7 @@ * {@link PerspectiveActivity}, {@link AbstractWorkbenchPerspectiveActivity}, and {@link WorkbenchPerspective}; and so * on. */ +@JsType public interface WorkbenchActivity extends ContextSensitiveActivity { /** @@ -109,9 +114,21 @@ public interface WorkbenchActivity extends ContextSensitiveActivity { String getTitle(); + @JsIgnore IsWidget getTitleDecoration(); + + default Element getTitleDecorationElement() { + IsWidget titleDecoration = getTitleDecoration(); + return (titleDecoration == null) ? null : titleDecoration.asWidget().getElement(); + } + @JsIgnore IsWidget getWidget(); + + default Element getWidgetElement() { + IsWidget widget = getWidget(); + return (widget == null) ? null : widget.asWidget().getElement(); + } Menus getMenus(); @@ -124,18 +141,23 @@ public interface WorkbenchActivity extends ContextSensitiveActivity { * first displaying it. Has no effect when the activity is added to a pre-existing panel, including the case where * the activity is added to a panel as part of a default perspective layout. * - * @return the height, in pixels, that should be allocated for a new panel created to house this activity. Null + * @return the height, in pixels, that should be allocated for a new panel created to house this activity. -1 (default) * means no particular height is preferred, and the framework can choose a default height. */ - Integer preferredHeight(); + default int preferredHeight() { + return -1; + } /** * Returns the amount of space that should be allocated to this activity if a new Workbench Panel is created when * first displaying it. Has no effect when the activity is added to a pre-existing panel, including the case where * the activity is added to a panel as part of a default perspective layout. * - * @return the width, in pixels, that should be allocated for a new panel created to house this activity. Null + * @return the width, in pixels, that should be allocated for a new panel created to house this activity. -1 (default) * means no particular width is preferred, and the framework can choose a default width. */ - Integer preferredWidth(); + default int preferredWidth() { + return -1; + } + } diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/WorkbenchEditorActivity.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/WorkbenchEditorActivity.java index 08d60f3487..b9677490ec 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/WorkbenchEditorActivity.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/mvp/WorkbenchEditorActivity.java @@ -17,6 +17,8 @@ import org.uberfire.backend.vfs.ObservablePath; import org.uberfire.mvp.PlaceRequest; +import org.uberfire.security.ResourceType; +import org.uberfire.workbench.model.ActivityResourceType; /** * An Editor is an activity that is associated with a VFS path. It is expected that the editor will provide the end user @@ -30,5 +32,10 @@ public void onStartup( final ObservablePath path, public void onSave(); public boolean isDirty(); + + @Override + default ResourceType getResourceType() { + return ActivityResourceType.EDITOR; + } } diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/PanelManagerImpl.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/PanelManagerImpl.java index f79920bebe..e052b0d094 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/PanelManagerImpl.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/PanelManagerImpl.java @@ -16,6 +16,9 @@ package org.uberfire.client.workbench; +import static org.uberfire.commons.validation.PortablePreconditions.checkNotNull; +import static org.uberfire.plugin.PluginUtil.*; + import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.event.logical.shared.AttachEvent; @@ -49,13 +52,9 @@ import javax.enterprise.event.Observes; import javax.enterprise.inject.Instance; import javax.inject.Inject; -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; -import static org.uberfire.commons.validation.PortablePreconditions.checkNotNull; - /** * Standard implementation of {@link PanelManager}. */ @@ -268,7 +267,7 @@ public void removeWorkbenchPanel( final PanelDefinition toRemove ) throws Illega if ( toRemove.isRoot() ) { throw new IllegalArgumentException( "The root panel cannot be removed. To replace it, call setRoot()" ); } - if ( !toRemove.getParts().isEmpty() ) { + if ( !toRemove.getParts().isEmpty()) { throw new IllegalStateException( "Panel still contains parts: " + toRemove.getParts() ); } @@ -333,7 +332,7 @@ public void onPartLostFocus() { @Override public void onPanelFocus( final PanelDefinition panel ) { for ( Map.Entry e : mapPanelDefinitionToPresenter.entrySet() ) { - e.getValue().setFocus( e.getKey().equals( panel ) ); + e.getValue().setFocus( e.getKey().asString().equals( panel.asString() ) ); } } @@ -349,8 +348,8 @@ private void onSelectPlaceEvent( @Observes SelectPlaceEvent event ) { // TODO (hbraun): PanelDefinition is not distinct (missing hashcode) for ( Map.Entry e : mapPanelDefinitionToPresenter.entrySet() ) { WorkbenchPanelPresenter panelPresenter = e.getValue(); - for (PartDefinition part : panelPresenter.getDefinition().getParts()) { - if (part.getPlace().equals(place)) { + for (PartDefinition part : ensureIterable ( panelPresenter.getDefinition().getParts() ) ) { + if (part.getPlace().asString().equals(place.asString())) { panelPresenter.selectPart(part); onPanelFocus(e.getKey()); } @@ -383,7 +382,7 @@ public PanelDefinition getPanelForPlace( final PlaceRequest place ) { */ protected PartDefinition getPartForPlace( final PlaceRequest place ) { for ( PartDefinition part : mapPartDefinitionToPresenter.keySet() ) { - if ( part.getPlace().equals( place ) ) { + if ( part.getPlace().asString().equals( place.asString() ) ) { return part; } } @@ -398,7 +397,7 @@ private void onChangeTitleWidgetEvent( @Observes ChangeTitleWidgetEvent event ) for ( Map.Entry e : mapPanelDefinitionToPresenter.entrySet() ) { final PanelDefinition panel = e.getKey(); final WorkbenchPanelPresenter presenter = e.getValue(); - for ( PartDefinition part : panel.getParts() ) { + for ( PartDefinition part : ensureIterable ( panel.getParts() ) ) { if ( place.equals( part.getPlace() ) ) { mapPartDefinitionToPresenter.get( part ).setTitle( title ); presenter.changeTitle( part, title, titleDecoration ); @@ -443,9 +442,12 @@ public PanelDefinition addWorkbenchPanel( final PanelDefinition targetPanel, } PanelDefinition newPanel; - if ( position == CompassPosition.ROOT ) { + // Position instance could come from a different script so we convert + // it to the local type here first in order for == to work. + CompassPosition cp = CompassPosition.valueOf( "" + position ); + if ( cp == CompassPosition.ROOT ) { newPanel = rootPanelDef; - } else if ( position == CompassPosition.SELF ) { + } else if ( cp == CompassPosition.SELF ) { newPanel = targetPanelPresenter.getDefinition(); } else { String defaultChildType = targetPanelPresenter.getDefaultChildType(); @@ -463,7 +465,7 @@ public PanelDefinition addWorkbenchPanel( final PanelDefinition targetPanel, childPanelPresenter ); targetPanelPresenter.addPanel( childPanelPresenter, - position ); + cp ); newPanel = childPanel; } @@ -513,8 +515,7 @@ public void onAttachOrDetach( AttachEvent event ) { @Override public void execute() { try { - List parts = new ArrayList( panelPresenter.getDefinition().getParts() ); - for ( PartDefinition part : parts ) { + for ( PartDefinition part : ensureIterable( panelPresenter.getDefinition().getParts() ) ) { placeManager.get().closePlace( part.getPlace() ); } diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/PluginEntryPoint.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/PluginEntryPoint.java new file mode 100644 index 0000000000..37ae23ce9c --- /dev/null +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/PluginEntryPoint.java @@ -0,0 +1,45 @@ +/* + * 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.client.workbench; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Produces; +import javax.inject.Inject; + +import org.jboss.errai.ioc.client.api.EnabledByProperty; +import org.jboss.errai.ioc.client.api.EntryPoint; +import org.jboss.errai.security.shared.api.identity.User; +import org.uberfire.client.mvp.PlaceManager; +import org.uberfire.rpc.SessionInfo; +import org.uberfire.rpc.impl.SessionInfoImpl; + +@EntryPoint +@EnabledByProperty(value = "uberfire.plugin.mode.active") +public class PluginEntryPoint { + + // Don't remove this injection point. It makes sure placeManager doesn't + // get pruned in case -Derrai.ioc.reachability=Aggressive + @SuppressWarnings("unused") + @Inject + private PlaceManager placeManager; + + @Produces + @ApplicationScoped + private SessionInfo currentSession(User identity) { + return new SessionInfoImpl( identity ); + } + +} diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/StandaloneEditorPerspective.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/StandaloneEditorPerspective.java index e2dddf3090..ad5e1614ff 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/StandaloneEditorPerspective.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/StandaloneEditorPerspective.java @@ -15,9 +15,6 @@ */ package org.uberfire.client.workbench; -import java.util.Collection; -import java.util.Collections; - import javax.enterprise.context.Dependent; import javax.inject.Inject; import javax.inject.Named; @@ -48,4 +45,5 @@ public PerspectiveDefinition getDefaultPerspectiveLayout() { public String getIdentifier() { return "StandaloneEditorPerspective"; } + } diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/Workbench.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/Workbench.java index eb4e91c488..7ad8739b4f 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/Workbench.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/Workbench.java @@ -30,10 +30,12 @@ import org.jboss.errai.bus.client.api.ClientMessageBus; import org.jboss.errai.bus.client.framework.ClientMessageBusImpl; import org.jboss.errai.ioc.client.api.AfterInitialization; +import org.jboss.errai.ioc.client.api.EnabledByProperty; import org.jboss.errai.ioc.client.api.EntryPoint; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.jboss.errai.security.shared.api.identity.User; +import org.slf4j.Logger; import org.uberfire.backend.vfs.Path; import org.uberfire.client.mvp.PerspectiveActivity; import org.uberfire.client.mvp.PlaceManager; @@ -44,6 +46,9 @@ import org.uberfire.mvp.impl.PathPlaceRequest; import org.uberfire.rpc.SessionInfo; import org.uberfire.rpc.impl.SessionInfoImpl; +import org.uberfire.security.authz.AuthorizationManager; +import org.uberfire.security.authz.AuthorizationPolicy; +import org.uberfire.security.authz.PermissionManager; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.Scheduler; @@ -54,9 +59,6 @@ import com.google.gwt.user.client.Window.ClosingEvent; import com.google.gwt.user.client.Window.ClosingHandler; import com.google.gwt.user.client.ui.RootLayoutPanel; -import org.uberfire.security.authz.AuthorizationManager; -import org.uberfire.security.authz.AuthorizationPolicy; -import org.uberfire.security.authz.PermissionManager; /** * Responsible for bootstrapping the client-side Workbench user interface by coordinating calls to the PanelManager and @@ -101,6 +103,7 @@ * */ @EntryPoint +@EnabledByProperty(value = "uberfire.plugin.mode.active", negated = true) public class Workbench { /** @@ -143,6 +146,9 @@ public class Workbench { @Inject private ClientMessageBus bus; + + @Inject + private Logger logger; private SessionInfo sessionInfo = null; @@ -220,8 +226,7 @@ private void earlyInit() { } private void bootstrap() { - - System.out.println("Workbench starting..."); + logger.info( "Starting workbench..." ); ( (SessionInfoImpl) currentSession() ).setId( ( (ClientMessageBusImpl) bus ).getSessionId() ); layout.setMarginWidgets( isStandaloneMode, headersToKeep ); @@ -236,7 +241,7 @@ private void bootstrap() { appReady.fire( new ApplicationReadyEvent() ); placeManager.goTo( new DefaultPlaceRequest( homePerspective.getIdentifier() ) ); } else { - Window.alert("No home perspective available!"); + logger.error( "No home perspective available!" ); } } else { handleStandaloneMode( Window.Location.getParameterMap() ); diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/WorkbenchLayout.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/WorkbenchLayout.java index f238f17299..4025b340b1 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/WorkbenchLayout.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/WorkbenchLayout.java @@ -16,7 +16,6 @@ package org.uberfire.client.workbench; -import java.util.List; import java.util.Set; import com.google.gwt.user.client.ui.HasWidgets; diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/panels/impl/AbstractDockingWorkbenchPanelPresenter.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/panels/impl/AbstractDockingWorkbenchPanelPresenter.java index d783dd4e52..e1ca819a37 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/panels/impl/AbstractDockingWorkbenchPanelPresenter.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/panels/impl/AbstractDockingWorkbenchPanelPresenter.java @@ -129,12 +129,15 @@ public boolean setChildSize( WorkbenchPanelPresenter child, for ( Map.Entry e : getPanels().entrySet() ) { if ( e.getValue() == child ) { int size; - if ( e.getKey() == CompassPosition.NORTH || e.getKey() == CompassPosition.SOUTH ) { + // Position instance could come from a different script so we convert + // it to the local type here first in order for == to work. + CompassPosition cp = CompassPosition.valueOf( "" + e.getKey() ); + if ( cp == CompassPosition.NORTH || cp == CompassPosition.SOUTH ) { if ( pixelHeight == null ) { return false; } size = pixelHeight + nestedPanelHeights( child ); - } else if ( e.getKey() == CompassPosition.EAST || e.getKey() == CompassPosition.WEST ) { + } else if ( cp == CompassPosition.EAST || cp == CompassPosition.WEST ) { if ( pixelWidth == null ) { return false; } diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/panels/impl/AbstractDockingWorkbenchPanelView.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/panels/impl/AbstractDockingWorkbenchPanelView.java index 6e06868d18..2dacb9321a 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/panels/impl/AbstractDockingWorkbenchPanelView.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/panels/impl/AbstractDockingWorkbenchPanelView.java @@ -16,6 +16,7 @@ package org.uberfire.client.workbench.panels.impl; +import static org.uberfire.plugin.PluginUtil.toInteger; import static org.uberfire.client.util.Layouts.*; import static org.uberfire.commons.validation.PortablePreconditions.*; @@ -320,10 +321,10 @@ static Integer minWidthOrHeight( CompassPosition position, PanelDefinition defin switch ( position ) { case NORTH: case SOUTH: - return definition.getMinHeight(); + return toInteger( definition.getMinHeightAsInt() ); case EAST: case WEST: - return definition.getMinWidth(); + return toInteger( definition.getMinWidthAsInt() ); default: throw new IllegalArgumentException( "Position " + position + " has no horizontal or vertial aspect." ); } } diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/panels/impl/AbstractWorkbenchPanelPresenter.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/panels/impl/AbstractWorkbenchPanelPresenter.java index c05f03ee2d..118d684bfd 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/panels/impl/AbstractWorkbenchPanelPresenter.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/panels/impl/AbstractWorkbenchPanelPresenter.java @@ -213,8 +213,13 @@ public WorkbenchPanelView

getPanelView() { @Override public void onResize( final int width, final int height ) { - getDefinition().setWidth( width == 0 ? null : width ); - getDefinition().setHeight( height == 0 ? null : height ); + if ( width != 0 ) { + getDefinition().setWidth( width ); + } + + if ( height != 0 ) { + getDefinition().setHeight( height ); + } } @Override diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/panels/impl/AdaptiveWorkbenchPanelPresenter.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/panels/impl/AdaptiveWorkbenchPanelPresenter.java index 6b5cc5402c..64dcd15731 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/panels/impl/AdaptiveWorkbenchPanelPresenter.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/panels/impl/AdaptiveWorkbenchPanelPresenter.java @@ -38,7 +38,7 @@ protected AdaptiveWorkbenchPanelPresenter asPresenterType() { @Override public String getDefaultChildType() { - if ( getDefinition().isRoot() && getDefinition().getParts().size() > 0 ) { + if ( getDefinition().isRoot() && !getDefinition().getParts().isEmpty() ) { return MultiListWorkbenchPanelPresenter.class.getName(); } else if ( getPanels().size() > 0 ) { return MultiListWorkbenchPanelPresenter.class.getName(); diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/panels/impl/SplitLayoutPanelView.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/panels/impl/SplitLayoutPanelView.java index 8e0ce25039..a4c040b8ef 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/panels/impl/SplitLayoutPanelView.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/panels/impl/SplitLayoutPanelView.java @@ -35,6 +35,8 @@ import com.google.gwt.user.client.ui.SplitLayoutPanel; import com.google.gwt.user.client.ui.Widget; +import static org.uberfire.plugin.PluginUtil.*; + import java.util.Collection; /** @@ -81,7 +83,7 @@ public void addPanel(PanelDefinition panel, WorkbenchPanelView view, Position po } else if ( CompassPosition.CENTER.equals( position ) ) { if ( activePanel != null ) { // close active parts of current panel - for ( PartDefinition part : activePanel.getK1().getParts() ) { + for ( PartDefinition part : ensureIterable( activePanel.getK1().getParts() ) ) { placeManager.closePlace( part.getPlace() ); } } diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/widgets/dnd/CompassDropController.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/widgets/dnd/CompassDropController.java index ec6a42d37a..33b8e691a2 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/widgets/dnd/CompassDropController.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/widgets/dnd/CompassDropController.java @@ -99,7 +99,7 @@ public void onDrop( DragContext context ) { //Source's tab within itself. If the Source Panel has only one Tab there is no //net effect. If we're trying to drop as a new tab there is no net effect. if ( sourcePanel.equals( dropPanel ) ) { - if ( sourcePanel.getParts().size() == 1 ) { + if ( sourcePanel.getParts() != null && sourcePanel.getParts().size() == 1 ) { return; } if ( p == CompassPosition.SELF ) { diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/widgets/dnd/WorkbenchPickupDragController.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/widgets/dnd/WorkbenchPickupDragController.java index ac5d63e985..dacb70d80d 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/widgets/dnd/WorkbenchPickupDragController.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/widgets/dnd/WorkbenchPickupDragController.java @@ -15,6 +15,7 @@ */ package org.uberfire.client.workbench.widgets.dnd; +import static org.uberfire.plugin.PluginUtil.toInteger; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; @@ -60,10 +61,10 @@ public void dragStart() { final IsWidget titleDecoration = sourceView.getPresenter().getTitleDecoration(); final String contextId = sourceView.getPresenter().getContextId(); final IsWidget widget = sourceView.getPresenter().getPartView().getWrappedWidget(); - final Integer height = sourcePanel.getHeight(); - final Integer width = sourcePanel.getWidth(); - final Integer minHeight = sourcePanel.getMinHeight(); - final Integer minWidth = sourcePanel.getMinWidth(); + final Integer height = toInteger ( sourcePanel.getHeightAsInt() ); + final Integer width = toInteger ( sourcePanel.getWidthAsInt() ); + final Integer minHeight = toInteger ( sourcePanel.getMinHeightAsInt() ); + final Integer minWidth = toInteger ( sourcePanel.getMinWidthAsInt() ); final WorkbenchDragContext context = new WorkbenchDragContext( place, sourcePart, sourcePanel, diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/widgets/menu/WorkbenchMenuBarPresenter.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/widgets/menu/WorkbenchMenuBarPresenter.java index 4b2809589f..6b86cd75de 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/widgets/menu/WorkbenchMenuBarPresenter.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/widgets/menu/WorkbenchMenuBarPresenter.java @@ -19,13 +19,12 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; + import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; 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.jboss.errai.ioc.client.container.IOC; import org.jboss.errai.security.shared.api.identity.User; import org.uberfire.client.menu.AuthFilterMenuVisitor; @@ -40,6 +39,7 @@ import org.uberfire.mvp.Command; import org.uberfire.mvp.PlaceRequest; import org.uberfire.security.authz.AuthorizationManager; +import org.uberfire.workbench.model.ActivityResourceType; import org.uberfire.workbench.model.menu.EnabledStateChangeListener; import org.uberfire.workbench.model.menu.MenuCustom; import org.uberfire.workbench.model.menu.MenuGroup; @@ -51,6 +51,9 @@ import org.uberfire.workbench.model.menu.Menus; import org.uberfire.workbench.model.menu.impl.BaseMenuVisitor; +import com.google.gwt.user.client.ui.IsWidget; +import com.google.gwt.user.client.ui.Widget; + /** * Presenter for WorkbenchMenuBar that mediates changes to the Workbench MenuBar * in response to changes to the selected WorkbenchPart. The menu structure is @@ -333,7 +336,7 @@ public void enabledStateChanged(final boolean enabled) { protected void onPerspectiveChange( @Observes final PerspectiveChange perspectiveChange ) { final Activity activity = activityManager.getActivity(perspectiveChange.getPlaceRequest()); - if( activity instanceof PerspectiveActivity ){ + if( activity!= null && activity.isType( ActivityResourceType.PERSPECTIVE.name() ) ) { addPerspectiveMenus( (PerspectiveActivity) activity); } view.selectMenuItem( perspectiveChange.getPlaceRequest().getIdentifier() ); diff --git a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/widgets/notfound/ActivityNotFoundPresenter.java b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/widgets/notfound/ActivityNotFoundPresenter.java index 9422ad1492..56b012349b 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/widgets/notfound/ActivityNotFoundPresenter.java +++ b/uberfire-workbench/uberfire-workbench-client/src/main/java/org/uberfire/client/workbench/widgets/notfound/ActivityNotFoundPresenter.java @@ -15,20 +15,19 @@ */ package org.uberfire.client.workbench.widgets.notfound; -import java.util.Collection; -import java.util.Collections; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import javax.inject.Named; -import com.google.gwt.user.client.ui.IsWidget; import org.uberfire.client.annotations.WorkbenchPopup.WorkbenchPopupSize; import org.uberfire.client.mvp.AbstractPopupActivity; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.mvp.UberView; import org.uberfire.client.workbench.widgets.popup.PopupView; +import com.google.gwt.user.client.ui.IsWidget; + @ApplicationScoped @Named("uf.workbench.activity.notfound") public class ActivityNotFoundPresenter extends AbstractPopupActivity { diff --git a/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/mvp/AbstractPopupActivityTest.java b/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/mvp/AbstractPopupActivityTest.java index e80f323c28..337cdb706c 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/mvp/AbstractPopupActivityTest.java +++ b/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/mvp/AbstractPopupActivityTest.java @@ -16,11 +16,13 @@ package org.uberfire.client.mvp; -import static org.mockito.Matchers.*; -import static org.mockito.Mockito.*; - -import java.util.Collection; -import java.util.Collections; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import org.junit.Before; import org.junit.Test; diff --git a/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/mvp/ActivityBeansCacheActivatedByTest.java b/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/mvp/ActivityBeansCacheActivatedByTest.java index b4944e57a5..b2215d024c 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/mvp/ActivityBeansCacheActivatedByTest.java +++ b/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/mvp/ActivityBeansCacheActivatedByTest.java @@ -163,7 +163,7 @@ public Class[] value() { @SuppressWarnings("unchecked") private SyncBeanDef mockRegularBean(Class type, T instance) { SyncBeanDef beanDef = mock( SyncBeanDef.class ); - when( iocManager.lookupBean( type ) ).thenReturn( beanDef ); + when( iocManager.lookupBeans( type.getName() ) ).thenReturn( Collections.singleton( beanDef ) ); when( beanDef.getInstance() ).thenReturn( instance ); when( beanDef.getBeanClass() ).thenReturn( (Class) type ); when( beanDef.isActivated() ).thenReturn( instance != null ); diff --git a/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/mvp/ActivityBeansCacheUnitTestWrapper.java b/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/mvp/ActivityBeansCacheUnitTestWrapper.java index 222fc9b38d..150237ed29 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/mvp/ActivityBeansCacheUnitTestWrapper.java +++ b/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/mvp/ActivityBeansCacheUnitTestWrapper.java @@ -39,7 +39,7 @@ public class ActivityBeansCacheUnitTestWrapper extends ActivityBeansCache { private SplashScreenActivity splashScreenActivity; private Collection> availableActivities = new HashSet>(); private List activitiesAndMetaInfo = new ArrayList(); - private Pair>> metaInfo; + private Pair> metaInfo; private boolean mockSplashcreen = true; public ActivityBeansCacheUnitTestWrapper() { @@ -98,7 +98,7 @@ List getResourceActivities() { } @Override - Pair>> generateActivityMetaInfo( SyncBeanDef activityBean ) { + Pair> generateActivityMetaInfo( SyncBeanDef activityBean ) { return metaInfo; } @@ -107,6 +107,6 @@ public void mockActivityBehaviour() { metaInfo = mock(Pair.class); when( metaInfo.getK1() ).thenReturn( new Integer(1) ); - when( metaInfo.getK2() ).thenReturn( new ArrayList>( ) ); + when( metaInfo.getK2() ).thenReturn( new ArrayList( ) ); } } diff --git a/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/mvp/ActivityManagerActivatedByTest.java b/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/mvp/ActivityManagerActivatedByTest.java index 15d11e4ecd..ab307ed1a1 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/mvp/ActivityManagerActivatedByTest.java +++ b/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/mvp/ActivityManagerActivatedByTest.java @@ -100,7 +100,7 @@ public void setup() { // We set this up assuming ActivityBeansCache is well-behaved, and hides the existence of inactive beans. // (of course this assumption is verified in a separate test) ActivityAndMetaInfo activatedActivityAndMetaInfo = - activityBeansCache.new ActivityAndMetaInfo( activatedActivityBean, 0, Collections.>emptyList() ); + activityBeansCache.new ActivityAndMetaInfo( activatedActivityBean, 0, Collections.emptyList() ); when( activityBeansCache.getResourceActivities() ).thenReturn( singletonList( activatedActivityAndMetaInfo ) ); when( activityBeansCache.getActivity( "activated activity" ) ).thenReturn( activatedActivityBean ); } diff --git a/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/mvp/ActivityMetaInfoTest.java b/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/mvp/ActivityMetaInfoTest.java index bb793d70c5..0af75fc121 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/mvp/ActivityMetaInfoTest.java +++ b/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/mvp/ActivityMetaInfoTest.java @@ -16,16 +16,22 @@ package org.uberfire.client.mvp; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; +import org.jboss.errai.ioc.client.container.DynamicAnnotation; import org.jboss.errai.ioc.client.container.IOCBeanDef; import org.junit.Test; import org.uberfire.client.workbench.annotations.AssociatedResources; @@ -40,15 +46,14 @@ public void generateNotGenerateActivityMetaInfo() { IOCBeanDef beanDefinition = mock( IOCBeanDef.class ); when( beanDefinition.getQualifiers() ).thenReturn( Collections.emptySet() ); - Pair>> nullGenerated = ActivityMetaInfo.generate( beanDefinition ); + Pair> nullGenerated = ActivityMetaInfo.generate( beanDefinition ); assertNull( nullGenerated ); - } @Test + @SuppressWarnings("unchecked") public void generateActivityMetaInfo() { - IOCBeanDef beanDefinition = mock( IOCBeanDef.class ); Priority priority = mock( Priority.class ); Integer priorityValue = 1; @@ -60,7 +65,7 @@ public void generateActivityMetaInfo() { final List> typesList = new ArrayList>(); typesList.add(ClientResourceType.class); - Class[] array = toArray( typesList ); + Class[] array = typesList.toArray( new Class[typesList.size()] ); when(associatedResources.value()).thenReturn( array ); qualifiers.add( associatedResources ); @@ -68,18 +73,37 @@ public void generateActivityMetaInfo() { when( beanDefinition.getQualifiers() ).thenReturn( qualifiers ); - Pair>> generated = ActivityMetaInfo.generate( beanDefinition ); + Pair> generated = ActivityMetaInfo.generate( beanDefinition ); assertEquals( priorityValue, generated.getK1() ); - assertTrue(generated.getK2().contains(ClientResourceType.class )); + assertTrue( generated.getK2().contains( ClientResourceType.class.getName() ) ); } + + @Test + public void generateActivityMetaInfoForDynamicActivity() { + final String otherResourceType = "org.uberfire.OtherResourceType"; + IOCBeanDef beanDefinition = mock( IOCBeanDef.class ); + + DynamicAnnotation priority = mock( DynamicAnnotation.class ); + when(priority.getName()).thenReturn( Priority.class.getName() ); + when(priority.getMember("value")).thenReturn( "1" ); - private static T[] toArray(List list) { - T[] toR = (T[]) java.lang.reflect.Array.newInstance(list.get(0) - .getClass(), list.size()); - for (int i = 0; i < list.size(); i++) { - toR[i] = list.get(i); - } - return toR; + Set qualifiers = new HashSet(); + DynamicAnnotation associatedResources = mock( DynamicAnnotation.class ); + when(associatedResources.getName()).thenReturn( AssociatedResources.class.getName() ); + when(associatedResources.getMember("value")).thenReturn( "[" + ClientResourceType.class.getName() + "," + otherResourceType + "]" ); + + qualifiers.add( associatedResources ); + qualifiers.add( priority ); + + when( beanDefinition.isDynamic() ).thenReturn( true ); + when( beanDefinition.getQualifiers() ).thenReturn( qualifiers ); + + Pair> generated = ActivityMetaInfo.generate( beanDefinition ); + + assertEquals( Integer.valueOf( 1 ), generated.getK1() ); + assertTrue( generated.getK2().contains( ClientResourceType.class.getName() ) ); + assertTrue( generated.getK2().contains( "org.uberfire.OtherResourceType" ) ); } + } diff --git a/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/mvp/PlaceRequestHistoryMapperImplTest.java b/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/mvp/PlaceRequestHistoryMapperImplTest.java index e4efe7c621..828f827287 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/mvp/PlaceRequestHistoryMapperImplTest.java +++ b/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/mvp/PlaceRequestHistoryMapperImplTest.java @@ -44,7 +44,6 @@ import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.PathPlaceRequest; -import com.google.common.collect.ImmutableMap; import com.google.gwtmockito.GwtMockitoTestRunner; @RunWith(GwtMockitoTestRunner.class) @@ -121,6 +120,6 @@ public void createPathPlaceRequestWithSpaces() throws Exception { public void identifierAndParametersShouldBeUrlDecoded() throws Exception { PlaceRequest placeRequest = placeRequestHistoryMapper.getPlaceRequest( "place%20id?par%26am%201=value%201" ); assertEquals( "place id", placeRequest.getIdentifier() ); - assertEquals( ImmutableMap.of( "par&am 1", "value 1" ), placeRequest.getParameters() ); + assertEquals( placeRequest.getParameters().get( "par&am 1" ), "value 1" ); } } diff --git a/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/mvp/WorkbenchEditorActivityTest.java b/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/mvp/WorkbenchEditorActivityTest.java index 4aaf1dbffc..d3c9d0b606 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/mvp/WorkbenchEditorActivityTest.java +++ b/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/mvp/WorkbenchEditorActivityTest.java @@ -14,24 +14,37 @@ * limitations under the License. */ + package org.uberfire.client.mvp; -import java.util.Collection; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.uberfire.client.annotations.WorkbenchEditor.LockingStrategy.EDITOR_PROVIDED; +import static org.uberfire.client.annotations.WorkbenchEditor.LockingStrategy.FRAMEWORK_PESSIMISTIC; + import javax.enterprise.inject.Instance; -import com.google.gwt.user.client.ui.IsWidget; 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.runners.MockitoJUnitRunner; +import org.mockito.stubbing.Answer; import org.uberfire.backend.vfs.ObservablePath; +import org.uberfire.backend.vfs.Path; import org.uberfire.client.annotations.WorkbenchEditor.LockingStrategy; +import org.uberfire.mvp.PlaceRequest; +import org.uberfire.mvp.impl.ExternalPathPlaceRequest; import org.uberfire.mvp.impl.PathPlaceRequest; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.*; -import static org.uberfire.client.annotations.WorkbenchEditor.LockingStrategy.*; +import com.google.gwt.user.client.ui.IsWidget; @RunWith(MockitoJUnitRunner.class) public class WorkbenchEditorActivityTest { @@ -44,10 +57,16 @@ public class WorkbenchEditorActivityTest { @Mock private PathPlaceRequest place; - + @Mock private ObservablePath path; + @Mock + private ExternalPathPlaceRequest extPlace; + + @Mock + private Path plainPath; + @Mock private IsWidget isWidget; @@ -92,6 +111,11 @@ protected LockingStrategy getLockingStrategy() { return strategy; } + @Override + public boolean isDynamic() { + return true; + } + } @Test @@ -147,5 +171,23 @@ public void frameworkProvidedLockingReleasesLocks() { verify( lockManagerProvider, times( 1 ) ).destroy( eq( lockManager ) ); verify( lockManager, times( 1 ) ).releaseLock(); } + + @Test + public void editorCreatesObservablePathForExternalPlaceRequest() { + EditorTestActivity activity = Mockito.spy( new EditorTestActivity( lockManagerProvider, + placeManager, + EDITOR_PROVIDED ) ); + + doAnswer(new Answer() { + public Void answer(InvocationOnMock invocation) { + return null; + } + }).when(activity).onStartup( any(Path.class), any(PlaceRequest.class) ); + + when( extPlace.getPath() ).thenReturn( plainPath ); + activity.onStartup( extPlace ); + + verify( activity).onStartup( any(Path.class), any(PlaceRequest.class) ); + } } \ No newline at end of file diff --git a/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/workbench/WorkbenchStartupTest.java b/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/workbench/WorkbenchStartupTest.java index feec3bddde..be09ddf710 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/workbench/WorkbenchStartupTest.java +++ b/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/workbench/WorkbenchStartupTest.java @@ -16,8 +16,12 @@ package org.uberfire.client.workbench; -import static org.mockito.Matchers.*; -import static org.mockito.Mockito.*; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import java.lang.annotation.Annotation; import java.util.Arrays; @@ -36,14 +40,12 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; +import org.slf4j.Logger; import org.uberfire.client.mvp.PerspectiveActivity; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.workbench.events.ApplicationReadyEvent; import org.uberfire.client.workbench.widgets.dnd.WorkbenchDragAndDropManager; import org.uberfire.client.workbench.widgets.dnd.WorkbenchPickupDragController; - -import com.google.gwt.user.client.ui.AbsolutePanel; -import com.google.gwtmockito.GwtMockitoTestRunner; import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.security.Resource; @@ -51,6 +53,9 @@ import org.uberfire.security.authz.AuthorizationPolicy; import org.uberfire.security.authz.PermissionManager; +import com.google.gwt.user.client.ui.AbsolutePanel; +import com.google.gwtmockito.GwtMockitoTestRunner; + @RunWith( GwtMockitoTestRunner.class ) public class WorkbenchStartupTest { @@ -74,6 +79,7 @@ public class WorkbenchStartupTest { @Mock SyncBeanDef perspectiveBean2; @Mock PerspectiveActivity perspectiveActivity1; @Mock PerspectiveActivity perspectiveActivity2; + @Mock Logger logger; @Before public void setup() { diff --git a/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/workbench/panels/impl/PlaceManagerTest.java b/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/workbench/panels/impl/PlaceManagerTest.java index 35624a7c83..5611765d36 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/workbench/panels/impl/PlaceManagerTest.java +++ b/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/workbench/panels/impl/PlaceManagerTest.java @@ -42,6 +42,7 @@ import org.uberfire.client.mvp.AbstractPopupActivity; import org.uberfire.client.mvp.Activity; import org.uberfire.client.mvp.ActivityManager; +import org.uberfire.workbench.model.ActivityResourceType; import org.uberfire.client.mvp.ContextActivity; import org.uberfire.client.mvp.PerspectiveActivity; import org.uberfire.client.mvp.PerspectiveManager; @@ -135,8 +136,11 @@ public void setup() { // every test starts in Kansas, with no side effect interactions recorded when( activityManager.getActivities( kansas ) ).thenReturn( singleton( (Activity) kansasActivity ) ); - setupPanelManagerMock(); + + when( kansasActivity.isType( ActivityResourceType.SCREEN.name() ) ).thenReturn( true ); + when( kansasActivity.isDynamic( ) ).thenReturn( false ); + placeManager.goTo( kansas, (PanelDefinition) null ); resetInjectedMocks(); reset( kansasActivity ); @@ -213,8 +217,10 @@ public void testPlaceManagerGetsInitializedToADefaultPlace() throws Exception { public void testGoToNewPlaceById() throws Exception { PlaceRequest oz = new DefaultPlaceRequest( "oz" ); WorkbenchScreenActivity ozActivity = mock( WorkbenchScreenActivity.class ); - when( ozActivity.preferredWidth() ).thenReturn( null ); - when( ozActivity.preferredHeight() ).thenReturn( null ); + when( ozActivity.isType( ActivityResourceType.SCREEN.name() ) ).thenReturn( true ); + when( ozActivity.isDynamic( ) ).thenReturn( false ); + when( ozActivity.preferredWidth() ).thenReturn( -1 ); + when( ozActivity.preferredHeight() ).thenReturn( -1 ); when( activityManager.getActivities( oz ) ).thenReturn( singleton( (Activity) ozActivity ) ); placeManager.goTo( oz, (PanelDefinition) null ); @@ -224,7 +230,7 @@ public void testGoToNewPlaceById() throws Exception { @Test public void testGoToPlaceWeAreAlreadyAt() throws Exception { - + when( kansasActivity.isType( ActivityResourceType.SCREEN.name() ) ).thenReturn( true ); placeManager.goTo( kansas, (PanelDefinition) null ); // note "refEq" tests equality field by field using reflection. don't read it as "reference equals!" :) @@ -254,7 +260,8 @@ public void testGoToPlaceByPath() throws Exception { PathPlaceRequest yellowBrickRoad = new FakePathPlaceRequest( mock( ObservablePath.class ) ); WorkbenchScreenActivity ozActivity = mock( WorkbenchScreenActivity.class ); - + + when( ozActivity.isType( ActivityResourceType.SCREEN.name() ) ).thenReturn( true ); when( activityManager.getActivities( yellowBrickRoad ) ).thenReturn( singleton( (Activity) ozActivity ) ); placeManager.goTo( yellowBrickRoad, (PanelDefinition) null ); @@ -285,6 +292,7 @@ public int hashCode() { @Test public void testNormalCloseExistingScreenActivity() throws Exception { when( kansasActivity.onMayClose() ).thenReturn( true ); + when( kansasActivity.isType( ActivityResourceType.SCREEN.name() ) ).thenReturn( true ); placeManager.closePlace( kansas ); @@ -304,6 +312,7 @@ public void testNormalCloseExistingScreenActivity() throws Exception { @Test public void testCanceledCloseExistingScreenActivity() throws Exception { when( kansasActivity.onMayClose() ).thenReturn( false ); + when( kansasActivity.isType( ActivityResourceType.SCREEN.name() ) ).thenReturn( true ); placeManager.closePlace( kansas ); @@ -322,6 +331,8 @@ public void testCanceledCloseExistingScreenActivity() throws Exception { @Test public void testForceCloseExistingScreenActivity() throws Exception { + when( kansasActivity.isType( ActivityResourceType.SCREEN.name() ) ).thenReturn( true ); + placeManager.forceClosePlace( kansas ); verify( workbenchPartBeforeCloseEvent ).fire( refEq( new BeforeClosePlaceEvent( kansas, true, true ) ) ); @@ -350,7 +361,7 @@ public void testLaunchingEmptyPerspective() throws Exception { when( activityManager.getActivities( ozPerspectivePlace ) ).thenReturn( singleton( (Activity) ozPerspectiveActivity ) ); when( ozPerspectiveActivity.getDefaultPerspectiveLayout() ).thenReturn( ozPerspectiveDef ); when( ozPerspectiveActivity.getPlace() ).thenReturn( ozPerspectivePlace ); - + when( ozPerspectiveActivity.isType( ActivityResourceType.PERSPECTIVE.name() ) ).thenReturn( true ); placeManager.goTo( ozPerspectivePlace ); // verify perspective changed to oz @@ -372,7 +383,9 @@ public void testSwitchingPerspectives() throws Exception { when( activityManager.getActivities( ozPerspectivePlace ) ).thenReturn( singleton( (Activity) ozPerspectiveActivity ) ); when( ozPerspectiveActivity.getDefaultPerspectiveLayout() ).thenReturn( ozPerspectiveDef ); when( ozPerspectiveActivity.getPlace() ).thenReturn( ozPerspectivePlace ); - + when( ozPerspectiveActivity.isType( ActivityResourceType.PERSPECTIVE.name() ) ).thenReturn( true ); + when( kansasActivity.isType( ActivityResourceType.SCREEN.name() ) ).thenReturn( true ); + // we'll pretend we started in kansas PerspectiveActivity kansasPerspectiveActivity = mock( PerspectiveActivity.class ); when( perspectiveManager.getCurrentPerspective() ).thenReturn( kansasPerspectiveActivity ); @@ -426,12 +439,14 @@ public void testLaunchingActivityTiedToDifferentPerspective() throws Exception { when( activityManager.getActivities( ozPerspectivePlace ) ).thenReturn( singleton( (Activity) ozPerspectiveActivity ) ); when( ozPerspectiveActivity.getDefaultPerspectiveLayout() ).thenReturn( ozPerspectiveDef ); when( ozPerspectiveActivity.getPlace() ).thenReturn( ozPerspectivePlace ); - + when( ozPerspectiveActivity.isType( ActivityResourceType.PERSPECTIVE.name() ) ).thenReturn( true ); + PlaceRequest emeraldCityPlace = new DefaultPlaceRequest( "emerald_city" ); WorkbenchScreenActivity emeraldCityActivity = mock( WorkbenchScreenActivity.class ); when( activityManager.getActivities( emeraldCityPlace ) ).thenReturn( singleton( (Activity) emeraldCityActivity ) ); when( emeraldCityActivity.getOwningPlace() ).thenReturn( ozPerspectivePlace ); - + when( emeraldCityActivity.isType( ActivityResourceType.SCREEN.name() ) ).thenReturn( true ); + placeManager.goTo( emeraldCityPlace, (PanelDefinition) null ); // verify perspective changed to oz @@ -458,7 +473,9 @@ public void testPerspectiveLaunchWithSplashScreen() throws Exception { final SplashScreenActivity splashScreenActivity = mock( SplashScreenActivity.class ); when( activityManager.getSplashScreenInterceptor( perspectivePlace ) ).thenReturn( splashScreenActivity ); - + when( perspectiveActivity.isType( ActivityResourceType.PERSPECTIVE.name() ) ).thenReturn( true ); + when( splashScreenActivity.isType( ActivityResourceType.SPLASH.name() ) ).thenReturn( true ); + placeManager.goTo( perspectivePlace ); // splash screen should be open and registered as an active splash screen @@ -483,17 +500,21 @@ public void testProperSplashScreenShutdownOnPerspectiveSwitch() throws Exception final PerspectiveActivity perspectiveActivity = mock( PerspectiveActivity.class ); final PerspectiveDefinition perspectiveDef = new PerspectiveDefinitionImpl( SimpleWorkbenchPanelPresenter.class.getName() ); when( perspectiveActivity.getDefaultPerspectiveLayout() ).thenReturn( perspectiveDef ); + when( perspectiveActivity.isType( ActivityResourceType.PERSPECTIVE.name() ) ).thenReturn( true ); when( activityManager.getActivities( perspectivePlace ) ).thenReturn( singleton( (Activity) perspectiveActivity ) ); // first splash screen: linked to the perspective itself final SplashScreenActivity splashScreenActivity1 = mock( SplashScreenActivity.class ); when( activityManager.getSplashScreenInterceptor( perspectivePlace ) ).thenReturn( splashScreenActivity1 ); + when( splashScreenActivity1.isType( ActivityResourceType.SPLASH.name() ) ).thenReturn( true ); // second splash screen: linked to a screen that we will display in the perspective final SplashScreenActivity splashScreenActivity2 = mock( SplashScreenActivity.class ); when( activityManager.getSplashScreenInterceptor( kansas ) ).thenReturn( splashScreenActivity2 ); when( activityManager.getActivities( kansas ) ).thenReturn( singleton( (Activity) kansasActivity ) ); - + when( splashScreenActivity2.isType( ActivityResourceType.SPLASH.name() ) ).thenReturn( true ); + when( kansasActivity.isType( ActivityResourceType.SCREEN.name() ) ).thenReturn( true ); + placeManager.goTo( perspectivePlace ); placeManager.goTo( kansas ); @@ -505,6 +526,7 @@ public void testProperSplashScreenShutdownOnPerspectiveSwitch() throws Exception final PerspectiveActivity otherPerspectiveActivity = mock( PerspectiveActivity.class ); final PerspectiveDefinition otherPerspectiveDef = new PerspectiveDefinitionImpl( SimpleWorkbenchPanelPresenter.class.getName() ); when( otherPerspectiveActivity.getDefaultPerspectiveLayout() ).thenReturn( otherPerspectiveDef ); + when( otherPerspectiveActivity.isType( ActivityResourceType.PERSPECTIVE.name() ) ).thenReturn( true ); when( activityManager.getActivities( otherPerspectivePlace ) ).thenReturn( singleton( (Activity) otherPerspectiveActivity ) ); placeManager.goTo( otherPerspectivePlace ); @@ -523,9 +545,11 @@ public void testPartLaunchWithSplashScreen() throws Exception { PlaceRequest oz = new DefaultPlaceRequest( "oz" ); WorkbenchScreenActivity ozActivity = mock( WorkbenchScreenActivity.class ); when( activityManager.getActivities( oz ) ).thenReturn( singleton( (Activity) ozActivity ) ); + when( ozActivity.isType( ActivityResourceType.SCREEN.name() ) ).thenReturn( true ); final SplashScreenActivity lollipopGuildActivity = mock( SplashScreenActivity.class ); when( activityManager.getSplashScreenInterceptor( oz ) ).thenReturn( lollipopGuildActivity ); + when( lollipopGuildActivity.isType( ActivityResourceType.SPLASH.name() ) ).thenReturn( true ); placeManager.goTo( oz, (PanelDefinition) null ); @@ -544,8 +568,10 @@ public void testProperSplashScreenShutdownOnPartClose() throws Exception { when( activityManager.getActivities( oz ) ).thenReturn( singleton( (Activity) ozActivity ) ); final SplashScreenActivity lollipopGuildActivity = mock( SplashScreenActivity.class ); + when( lollipopGuildActivity.isType( ActivityResourceType.SPLASH.name() ) ).thenReturn( true ); when( activityManager.getSplashScreenInterceptor( oz ) ).thenReturn( lollipopGuildActivity ); - + when( ozActivity.isType( ActivityResourceType.SCREEN.name() ) ).thenReturn( true ); + placeManager.goTo( oz, (PanelDefinition) null ); placeManager.closePlace( oz ); @@ -601,7 +627,8 @@ public void testLaunchingPopup() throws Exception { final AbstractPopupActivity popupActivity = mock( AbstractPopupActivity.class ); when( activityManager.getActivities( popupPlace ) ).thenReturn( singleton( (Activity) popupActivity ) ); - + when( popupActivity.isType( ActivityResourceType.POPUP.name() ) ).thenReturn( true ); + placeManager.goTo( popupPlace ); verify( popupActivity, never() ).onStartup( any( PlaceRequest.class ) ); @@ -620,7 +647,8 @@ public void testLaunchingPopupThatIsAlreadyOpen() throws Exception { final AbstractPopupActivity popupActivity = mock( AbstractPopupActivity.class ); when( activityManager.getActivities( popupPlace ) ).thenReturn( singleton( (Activity) popupActivity ) ); - + when( popupActivity.isType( ActivityResourceType.POPUP.name() ) ).thenReturn( true ); + placeManager.goTo( popupPlace ); placeManager.goTo( popupPlace ); @@ -636,7 +664,7 @@ public void testReLaunchingClosedPopup() throws Exception { final PlaceRequest popupPlace = new DefaultPlaceRequest( "Somewhere" ); final AbstractPopupActivity popupActivity = mock( AbstractPopupActivity.class ); when( popupActivity.onMayClose() ).thenReturn( true ); - + when( popupActivity.isType( ActivityResourceType.POPUP.name() ) ).thenReturn( true ); when( activityManager.getActivities( popupPlace ) ).thenReturn( singleton( (Activity) popupActivity ) ); placeManager.goTo( popupPlace ); @@ -654,7 +682,7 @@ public void testPopupCancelsClose() throws Exception { final PlaceRequest popupPlace = new DefaultPlaceRequest( "Somewhere" ); final AbstractPopupActivity popupActivity = mock( AbstractPopupActivity.class ); when( popupActivity.onMayClose() ).thenReturn( false ); - + when( popupActivity.isType( ActivityResourceType.POPUP.name() ) ).thenReturn( true ); when( activityManager.getActivities( popupPlace ) ).thenReturn( singleton( (Activity) popupActivity ) ); placeManager.goTo( popupPlace ); @@ -673,8 +701,9 @@ public void testLaunchActivityInCustomPanel() throws Exception { PlaceRequest emeraldCityPlace = new DefaultPlaceRequest( "emerald_city" ); WorkbenchScreenActivity emeraldCityActivity = mock( WorkbenchScreenActivity.class ); when( emeraldCityActivity.preferredWidth() ).thenReturn( 555 ); - when( emeraldCityActivity.preferredHeight() ).thenReturn( null ); + when( emeraldCityActivity.preferredHeight() ).thenReturn( -1 ); when( activityManager.getActivities( emeraldCityPlace ) ).thenReturn( singleton( (Activity) emeraldCityActivity ) ); + when( emeraldCityActivity.isType( ActivityResourceType.SCREEN.name() ) ).thenReturn( true ); HasWidgets customContainer = mock( HasWidgets.class ); @@ -696,6 +725,7 @@ public void testLaunchActivityInCustomPanel() throws Exception { public void testLaunchExistingActivityInCustomPanel() throws Exception { HasWidgets customContainer = mock( HasWidgets.class ); + when( kansasActivity.isType( ActivityResourceType.SCREEN.name() ) ).thenReturn( true ); placeManager.goTo( kansas, customContainer ); verify( panelManager, never() ).addCustomPanel( customContainer, StaticWorkbenchPanelPresenter.class.getName() ); @@ -713,7 +743,8 @@ public void testClosingActivityInCustomPanel() throws Exception { WorkbenchScreenActivity emeraldCityActivity = mock( WorkbenchScreenActivity.class ); when( emeraldCityActivity.onMayClose() ).thenReturn( true ); when( emeraldCityActivity.preferredWidth() ).thenReturn( 555 ); - when( emeraldCityActivity.preferredHeight() ).thenReturn( null ); + when( emeraldCityActivity.preferredHeight() ).thenReturn( -1 ); + when( emeraldCityActivity.isType( ActivityResourceType.SCREEN.name() )).thenReturn( true ); when( activityManager.getActivities( emeraldCityPlace ) ).thenReturn( singleton( (Activity) emeraldCityActivity ) ); HasWidgets customContainer = mock( HasWidgets.class ); @@ -735,7 +766,8 @@ public void testClosingAllPlacesIncludesCustomPanels() throws Exception { WorkbenchScreenActivity emeraldCityActivity = mock( WorkbenchScreenActivity.class ); when( emeraldCityActivity.onMayClose() ).thenReturn( true ); when( emeraldCityActivity.preferredWidth() ).thenReturn( 555 ); - when( emeraldCityActivity.preferredHeight() ).thenReturn( null ); + when( emeraldCityActivity.preferredHeight() ).thenReturn( -1 ); + when( emeraldCityActivity.isType( ActivityResourceType.SCREEN.name() ) ).thenReturn( true ); when( activityManager.getActivities( emeraldCityPlace ) ).thenReturn( singleton( (Activity) emeraldCityActivity ) ); HasWidgets customContainer = mock( HasWidgets.class ); @@ -754,6 +786,7 @@ public void testGetActivitiesForResourceType_NoMatches() throws Exception { final WorkbenchScreenActivity ozActivity = mock( WorkbenchScreenActivity.class ); when( activityManager.getActivities( yellowBrickRoad ) ).thenReturn( singleton( (Activity) ozActivity ) ); + when( ozActivity.isType( ActivityResourceType.SCREEN.name() ) ).thenReturn( true ); placeManager.goTo( yellowBrickRoad ); @@ -777,6 +810,7 @@ public void testGetActivitiesForResourceType_Matches() throws Exception { final WorkbenchScreenActivity ozActivity = mock( WorkbenchScreenActivity.class ); when( activityManager.getActivities( yellowBrickRoad ) ).thenReturn( singleton( (Activity) ozActivity ) ); + when( ozActivity.isType( ActivityResourceType.SCREEN.name() ) ).thenReturn( true ); placeManager.goTo( yellowBrickRoad ); diff --git a/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/workbench/widgets/menu/WorkbenchMenuBarPresenterTest.java b/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/workbench/widgets/menu/WorkbenchMenuBarPresenterTest.java index e3e6d78f58..266f6eb648 100644 --- a/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/workbench/widgets/menu/WorkbenchMenuBarPresenterTest.java +++ b/uberfire-workbench/uberfire-workbench-client/src/test/java/org/uberfire/client/workbench/widgets/menu/WorkbenchMenuBarPresenterTest.java @@ -16,6 +16,20 @@ package org.uberfire.client.workbench.widgets.menu; +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.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Matchers.isNull; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import org.jboss.errai.security.shared.api.identity.User; import org.junit.Test; import org.junit.runner.RunWith; @@ -35,13 +49,11 @@ import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.security.Resource; import org.uberfire.security.authz.AuthorizationManager; +import org.uberfire.workbench.model.ActivityResourceType; import org.uberfire.workbench.model.menu.MenuFactory; import org.uberfire.workbench.model.menu.MenuPosition; import org.uberfire.workbench.model.menu.Menus; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; - @RunWith(MockitoJUnitRunner.class) public class WorkbenchMenuBarPresenterTest { @@ -103,6 +115,7 @@ public void testPerspectiveChangeEvent() { final PerspectiveChange perspectiveChange = new PerspectiveChange( placeRequest, null, null, perspectiveId ); when( perspectiveActivity.getPlace() ).thenReturn( placeRequest ); + when (perspectiveActivity.isType( ActivityResourceType.PERSPECTIVE.name() )).thenReturn( true ); when( authzManager.authorize( any( Resource.class ), eq( identity ) ) ).thenReturn( true ); presenter.addMenus( menus ); @@ -148,8 +161,10 @@ public void testAddContextMenuWithPermission() { when( activity.getIdentifier() ).thenReturn( perspectiveId ); when( activity.getMenus() ).thenReturn( contextMenus ); + when (activity.isType( ActivityResourceType.PERSPECTIVE.name() )).thenReturn( true ); when( authzManager.authorize( contextMenus.getItems().get( 0 ), identity ) ).thenReturn( true ); when( activityManager.getActivity( placeRequest ) ).thenReturn( activity ); + presenter.onPerspectiveChange( new PerspectiveChange(placeRequest, null, contextMenus, perspectiveId) ); @@ -168,6 +183,7 @@ public void testAddContextMenuWithoutPermission() { when( activity.getIdentifier() ).thenReturn( perspectiveId ); when( activity.getMenus() ).thenReturn( contextMenus ); + when (activity.isType( ActivityResourceType.PERSPECTIVE.name() )).thenReturn( true ); when( authzManager.authorize( contextMenus.getItems().get( 0 ), identity ) ).thenReturn( false ); when( activityManager.getActivity( placeRequest ) ).thenReturn( activity ); @@ -239,6 +255,7 @@ public void testSetupEnableDisableContextMenuItem() { when( activity.getIdentifier() ).thenReturn( perspectiveId ); when( activity.getMenus() ).thenReturn( contextMenus ); + when (activity.isType( ActivityResourceType.PERSPECTIVE.name() )).thenReturn( true ); when( authzManager.authorize( contextMenus.getItems().get( 0 ), identity ) ).thenReturn( true ); when( activityManager.getActivity( placeRequest ) ).thenReturn( activity ); diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/java/org/uberfire/annotations/processors/PerspectiveProcessorTest.java b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/java/org/uberfire/annotations/processors/PerspectiveProcessorTest.java index 1aff82c43b..18420f1732 100644 --- a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/java/org/uberfire/annotations/processors/PerspectiveProcessorTest.java +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/java/org/uberfire/annotations/processors/PerspectiveProcessorTest.java @@ -395,6 +395,25 @@ public void combiningPerspectiveMethodAndWorkbenchPanelFieldsShouldGenerateAnErr assertFailedCompilation( diagnostics ); assertCompilationMessage( diagnostics, Kind.ERROR, 19, 8, "This WorkbenchPerspective has both a @Perspective method and a @WorkbenchPanel field. Only one or the other is allowed." ); } + + @Test + public void testDynamicPerspective() throws FileNotFoundException { + final String pathCompilationUnit = "org/uberfire/annotations/processors/PerspectiveTest24"; + final String pathExpectedResult = "org/uberfire/annotations/processors/expected/PerspectiveTest24.expected"; + + result.setExpectedCode( getExpectedSourceCode( pathExpectedResult ) ); + + final List> diagnostics = compile( + getProcessorUnderTest(), + pathCompilationUnit ); + + assertSuccessfulCompilation( diagnostics ); + assertNotNull( result.getActualCode() ); + assertNotNull( result.getExpectedCode() ); + assertEquals( result.getExpectedCode(), + result.getActualCode() ); + } + private void printDiagnostics( List> diagnostics ) { for ( Diagnostic diagnostic: diagnostics ){ diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/java/org/uberfire/annotations/processors/WorkbenchEditorProcessorTest.java b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/java/org/uberfire/annotations/processors/WorkbenchEditorProcessorTest.java index 5a070da977..7f36e65b5f 100644 --- a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/java/org/uberfire/annotations/processors/WorkbenchEditorProcessorTest.java +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/java/org/uberfire/annotations/processors/WorkbenchEditorProcessorTest.java @@ -483,4 +483,22 @@ public void testEditorWithLockingStrategy() throws FileNotFoundException { assertEquals( result.getExpectedCode(), result.getActualCode() ); } + + @Test + public void testDynamicWorkbenchEditor() throws FileNotFoundException { + final String pathCompilationUnit = "org/uberfire/annotations/processors/WorkbenchEditorTest28"; + final String pathExpectedResult = "org/uberfire/annotations/processors/expected/WorkbenchEditorTest28.expected"; + + result.setExpectedCode( getExpectedSourceCode( pathExpectedResult ) ); + + final List> diagnostics = compile( + getProcessorUnderTest(), + pathCompilationUnit ); + + assertSuccessfulCompilation( diagnostics ); + assertNotNull( result.getActualCode() ); + assertNotNull( result.getExpectedCode() ); + assertEquals( result.getExpectedCode(), + result.getActualCode() ); + } } diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/java/org/uberfire/annotations/processors/WorkbenchPopupProcessorTest.java b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/java/org/uberfire/annotations/processors/WorkbenchPopupProcessorTest.java index 315dee5636..d24a33edd5 100644 --- a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/java/org/uberfire/annotations/processors/WorkbenchPopupProcessorTest.java +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/java/org/uberfire/annotations/processors/WorkbenchPopupProcessorTest.java @@ -78,8 +78,8 @@ public void testWorkbenchPopupHasViewAnnotation() throws FileNotFoundException { assertSuccessfulCompilation( diagnostics ); assertNotNull( result.getActualCode() ); assertNotNull( result.getExpectedCode() ); - assertEquals( result.getActualCode(), - result.getExpectedCode() ); + assertEquals( result.getExpectedCode(), + result.getActualCode() ); } @Test @@ -96,8 +96,8 @@ public void testWorkbenchPopupExtendsIsWidget() throws FileNotFoundException { assertSuccessfulCompilation( diagnostics ); assertNotNull( result.getActualCode() ); assertNotNull( result.getExpectedCode() ); - assertEquals( result.getActualCode(), - result.getExpectedCode() ); + assertEquals( result.getExpectedCode(), + result.getActualCode() ); } @Test @@ -115,8 +115,8 @@ public void testWorkbenchPopupHasViewAnnotationAndExtendsIsWidget() throws FileN assertCompilationMessage( diagnostics, Kind.WARNING, Diagnostic.NOPOS, Diagnostic.NOPOS, "The WorkbenchPopup both extends com.google.gwt.user.client.ui.IsWidget and provides a @WorkbenchPartView annotated method. The annotated method will take precedence." ); assertNotNull( result.getActualCode() ); assertNotNull( result.getExpectedCode() ); - assertEquals( result.getActualCode(), - result.getExpectedCode() ); + assertEquals( result.getExpectedCode(), + result.getActualCode() ); } @Test @@ -133,8 +133,8 @@ public void testWorkbenchPopupAllAnnotations() throws FileNotFoundException { assertSuccessfulCompilation( diagnostics ); assertNotNull( result.getActualCode() ); assertNotNull( result.getExpectedCode() ); - assertEquals( result.getActualCode(), - result.getExpectedCode() ); + assertEquals( result.getExpectedCode(), + result.getActualCode() ); } @Test @@ -151,8 +151,8 @@ public void testWorkbenchPopupOnStart0Parameter() throws FileNotFoundException { assertSuccessfulCompilation( diagnostics ); assertNotNull( result.getActualCode() ); assertNotNull( result.getExpectedCode() ); - assertEquals( result.getActualCode(), - result.getExpectedCode() ); + assertEquals( result.getExpectedCode(), + result.getActualCode() ); } @Test @@ -169,8 +169,8 @@ public void testWorkbenchPopupOnStart1Parameter() throws FileNotFoundException { assertSuccessfulCompilation( diagnostics ); assertNotNull( result.getActualCode() ); assertNotNull( result.getExpectedCode() ); - assertEquals( result.getActualCode(), - result.getExpectedCode() ); + assertEquals( result.getExpectedCode(), + result.getActualCode() ); } @Test @@ -213,8 +213,8 @@ public void testWorkbenchPopupHasTitleAndTitleWidget() throws FileNotFoundExcept assertSuccessfulCompilation( diagnostics ); assertNotNull( result.getActualCode() ); assertNotNull( result.getExpectedCode() ); - assertEquals( result.getActualCode(), - result.getExpectedCode() ); + assertEquals( result.getExpectedCode(), + result.getActualCode() ); } @Test @@ -231,8 +231,8 @@ public void testPopupWithActivator() throws FileNotFoundException { assertSuccessfulCompilation( diagnostics ); assertNotNull( result.getActualCode() ); assertNotNull( result.getExpectedCode() ); - assertEquals( result.getActualCode(), - result.getExpectedCode() ); + assertEquals( result.getExpectedCode(), + result.getActualCode() ); } @Test @@ -249,7 +249,7 @@ public void testPopupSize() throws FileNotFoundException { assertSuccessfulCompilation( diagnostics ); assertNotNull( result.getActualCode() ); assertNotNull( result.getExpectedCode() ); - assertEquals( result.getActualCode(), - result.getExpectedCode() ); + assertEquals( result.getExpectedCode(), + result.getActualCode() ); } } diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/java/org/uberfire/annotations/processors/WorkbenchScreenProcessorTest.java b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/java/org/uberfire/annotations/processors/WorkbenchScreenProcessorTest.java index eec523adf5..649bb18850 100644 --- a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/java/org/uberfire/annotations/processors/WorkbenchScreenProcessorTest.java +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/java/org/uberfire/annotations/processors/WorkbenchScreenProcessorTest.java @@ -112,8 +112,8 @@ public void testWorkbenchScreenExtendsIsWidget() throws FileNotFoundException { assertSuccessfulCompilation( diagnostics ); assertNotNull( result.getActualCode() ); assertNotNull( result.getExpectedCode() ); - assertEquals( result.getActualCode(), - result.getExpectedCode() ); + assertEquals( result.getExpectedCode(), + result.getActualCode() ); } @Test @@ -130,8 +130,8 @@ public void testWorkbenchScreenHasViewAnnotationAndExtendsIsWidget() throws File assertCompilationMessage( diagnostics, Kind.WARNING, Diagnostic.NOPOS, Diagnostic.NOPOS, "The WorkbenchScreen both extends com.google.gwt.user.client.ui.IsWidget and provides a @WorkbenchPartView annotated method. The annotated method will take precedence." ); assertNotNull( result.getActualCode() ); assertNotNull( result.getExpectedCode() ); - assertEquals( result.getActualCode(), - result.getExpectedCode() ); + assertEquals( result.getExpectedCode(), + result.getActualCode() ); } @Test @@ -185,8 +185,8 @@ public void testWorkbenchScreenWorkbenchMenuAnnotationCorrectReturnType() throws assertSuccessfulCompilation( diagnostics ); assertNotNull( result.getActualCode() ); assertNotNull( result.getExpectedCode() ); - assertEquals( result.getActualCode(), - result.getExpectedCode() ); + assertEquals( result.getExpectedCode(), + result.getActualCode() ); } @Test @@ -264,8 +264,8 @@ public void testWorkbenchScreenWorkbenchToolBarAnnotationCorrectReturnType() thr assertSuccessfulCompilation( diagnostics ); assertNotNull( result.getActualCode() ); assertNotNull( result.getExpectedCode() ); - assertEquals( result.getActualCode(), - result.getExpectedCode() ); + assertEquals( result.getExpectedCode(), + result.getActualCode() ); } @Test @@ -309,8 +309,8 @@ public void testWorkbenchScreenHasTitleAndTitleWidget() throws FileNotFoundExcep assertSuccessfulCompilation( diagnostics ); assertNotNull( result.getActualCode() ); assertNotNull( result.getExpectedCode() ); - assertEquals( result.getActualCode(), - result.getExpectedCode() ); + assertEquals( result.getExpectedCode(), + result.getActualCode() ); } @Test @@ -469,7 +469,6 @@ public void testWorkbenchScreenHasTitleAndTitleWidgetWithNegativePreferredWidthA assertEquals( result.getActualCode(), result.getExpectedCode() ); } - @Test public void testWorkbenchScreenHasViewAnnotationIsElementAndHasTitleAnnotation() throws FileNotFoundException { final String pathCompilationUnit = "org/uberfire/annotations/processors/WorkbenchScreenTest29"; @@ -483,8 +482,8 @@ public void testWorkbenchScreenHasViewAnnotationIsElementAndHasTitleAnnotation() assertSuccessfulCompilation( diagnostics ); assertNotNull( result.getActualCode() ); assertNotNull( result.getExpectedCode() ); - assertEquals( result.getActualCode(), - result.getExpectedCode() ); + assertEquals( result.getExpectedCode(), + result.getActualCode() ); } @Test @@ -500,8 +499,8 @@ public void testWorkbenchScreenUberElement() throws FileNotFoundException { assertSuccessfulCompilation( diagnostics ); assertNotNull( result.getActualCode() ); assertNotNull( result.getExpectedCode() ); - assertEquals( result.getActualCode(), - result.getExpectedCode() ); + assertEquals( result.getExpectedCode(), + result.getActualCode() ); } @Test @@ -517,8 +516,8 @@ public void testWorkbenchScreenHasTitleAndTitleElement() throws FileNotFoundExce assertSuccessfulCompilation( diagnostics ); assertNotNull( result.getActualCode() ); assertNotNull( result.getExpectedCode() ); - assertEquals( result.getActualCode(), - result.getExpectedCode() ); + assertEquals( result.getExpectedCode(), + result.getActualCode() ); } @Test @@ -534,8 +533,24 @@ public void testWorkbenchScreenHasTitleAndTitleAndWidgetAsElement() throws FileN assertSuccessfulCompilation( diagnostics ); assertNotNull( result.getActualCode() ); assertNotNull( result.getExpectedCode() ); - assertEquals( result.getActualCode(), - result.getExpectedCode() ); + assertEquals( result.getExpectedCode(), + result.getActualCode() ); } + + @Test + public void testDynamicWorkbenchScreen() throws FileNotFoundException { + final String pathCompilationUnit = "org/uberfire/annotations/processors/WorkbenchScreenTest33"; + final String pathExpectedResult = "org/uberfire/annotations/processors/expected/WorkbenchScreenTest33.expected"; + + result.setExpectedCode( getExpectedSourceCode( pathExpectedResult ) ); + final List> diagnostics = compile( + getProcessorUnderTest(), + pathCompilationUnit ); + assertSuccessfulCompilation( diagnostics ); + assertNotNull( result.getActualCode() ); + assertNotNull( result.getExpectedCode() ); + assertEquals( result.getExpectedCode(), + result.getActualCode() ); + } } diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/PerspectiveTest24.java b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/PerspectiveTest24.java new file mode 100644 index 0000000000..cdf4b99d2a --- /dev/null +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/PerspectiveTest24.java @@ -0,0 +1,15 @@ +package org.uberfire.annotations.processors; + +import org.uberfire.client.annotations.Perspective; +import org.uberfire.client.annotations.WorkbenchPerspective; +import org.uberfire.workbench.model.PerspectiveDefinition; + +@WorkbenchPerspective(identifier = "PerspectiveTest24", isDynamic=true) +public class PerspectiveTest24 { + + @Perspective + public PerspectiveDefinition getPerspective() { + return null; + } + +} diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/WorkbenchEditorTest28.java b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/WorkbenchEditorTest28.java new file mode 100644 index 0000000000..e6838f51d3 --- /dev/null +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/WorkbenchEditorTest28.java @@ -0,0 +1,29 @@ +package org.uberfire.annotations.processors; + +import com.google.gwt.user.client.ui.IsWidget; +import com.google.gwt.user.client.ui.SimplePanel; +import org.uberfire.backend.vfs.Path; +import org.uberfire.client.annotations.WorkbenchEditor; +import org.uberfire.client.annotations.WorkbenchPartTitle; +import org.uberfire.client.annotations.WorkbenchPartView; +import org.uberfire.client.mvp.MyTestType; +import org.uberfire.lifecycle.OnStartup; + +@WorkbenchEditor(identifier = "test28", supportedTypes = {MyTestType.class}, isDynamic = true) +public class WorkbenchEditorTest28 { + + @WorkbenchPartView + public IsWidget getView() { + return new SimplePanel(); + } + + @WorkbenchPartTitle + public String getTitle() { + return "title"; + } + + @OnStartup + public void onStartup( final Path path ) { + } + +} diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/WorkbenchScreenTest29.java b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/WorkbenchScreenTest29.java index 4e5019ae86..c5d6e29b34 100644 --- a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/WorkbenchScreenTest29.java +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/WorkbenchScreenTest29.java @@ -34,4 +34,4 @@ public String getTitle() { return "title"; } -} +} \ No newline at end of file diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/WorkbenchScreenTest33.java b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/WorkbenchScreenTest33.java new file mode 100644 index 0000000000..e698b573d2 --- /dev/null +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/WorkbenchScreenTest33.java @@ -0,0 +1,26 @@ +package org.uberfire.annotations.processors; + +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.lifecycle.OnStartup; + +@WorkbenchScreen(identifier = "test33", isDynamic = true) +public class WorkbenchScreenTest33 { + + @WorkbenchPartView + public UberView getView() { + return null; + } + + @WorkbenchPartTitle + public String getTitle() { + return "title"; + } + + @OnStartup + public void onStartup() { + } + +} \ No newline at end of file diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/WorkbenchSplashScreenTest6.java b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/WorkbenchSplashScreenTest6.java index 0190a035af..5249866514 100644 --- a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/WorkbenchSplashScreenTest6.java +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/WorkbenchSplashScreenTest6.java @@ -26,4 +26,4 @@ public SplashScreenFilter getFilter() { return null; } -} +} \ No newline at end of file diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest10.expected b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest10.expected index 26f141450d..33e9513126 100644 --- a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest10.expected +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest10.expected @@ -62,5 +62,5 @@ public class PerspectiveTest10Activity extends AbstractWorkbenchPerspectiveActiv @Override public ToolBar getToolBar() { return realPresenter.getToolBar(); - } + } } diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest11.expected b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest11.expected index 2e5c9d347e..1010483b64 100644 --- a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest11.expected +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest11.expected @@ -56,4 +56,5 @@ public class PerspectiveTest11Activity extends AbstractWorkbenchPerspectiveActiv public PerspectiveDefinition getDefaultPerspectiveLayout() { return realPresenter.getPerspective(); } + } diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest20.expected b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest20.expected index 2b055cd068..8c143521b6 100644 --- a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest20.expected +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest20.expected @@ -59,4 +59,5 @@ public class PerspectiveTest20Activity extends AbstractWorkbenchPerspectiveActiv public PerspectiveDefinition getDefaultPerspectiveLayout() { return realPresenter.getPerspective(); } + } diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest21.expected b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest21.expected index 0c4bc78d97..c4c34b2518 100644 --- a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest21.expected +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest21.expected @@ -61,4 +61,5 @@ public class PerspectiveTest21Activity extends AbstractWorkbenchPerspectiveActiv public PerspectiveDefinition getDefaultPerspectiveLayout() { return realPresenter.getPerspective(); } + } diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest24.expected b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest24.expected new file mode 100644 index 0000000000..4592926e7f --- /dev/null +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest24.expected @@ -0,0 +1,68 @@ +/* + * 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.uberfire.annotations.processors; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import javax.annotation.Generated; +import javax.enterprise.context.Dependent; +import javax.inject.Inject; + +import javax.inject.Named; +import org.uberfire.workbench.model.PerspectiveDefinition; +import org.uberfire.client.mvp.AbstractWorkbenchPerspectiveActivity; +import org.uberfire.client.mvp.PlaceManager; + +import org.uberfire.mvp.PlaceRequest; + +import jsinterop.annotations.JsType; +import org.jboss.errai.ioc.client.api.Shared; + +@Dependent +@Generated("org.uberfire.annotations.processors.WorkbenchPerspectiveProcessor") +@Named("PerspectiveTest24") +@JsType +/* + * WARNING! This class is generated. Do not modify. + */ +public class PerspectiveTest24Activity extends AbstractWorkbenchPerspectiveActivity { + + @Inject + private PerspectiveTest24 realPresenter; + + @Inject + //Constructor injection for testing + public PerspectiveTest24Activity(@Shared final PlaceManager placeManager) { + super( placeManager ); + } + + @Override + public String getIdentifier() { + return "PerspectiveTest24"; + } + + @Override + public PerspectiveDefinition getDefaultPerspectiveLayout() { + return realPresenter.getPerspective(); + } + + @Override + public boolean isDynamic() { + return true; + } +} diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest4.expected b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest4.expected index 5416669b32..0b16a37e9e 100644 --- a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest4.expected +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest4.expected @@ -56,4 +56,5 @@ public class PerspectiveTest4Activity extends AbstractWorkbenchPerspectiveActivi public PerspectiveDefinition getDefaultPerspectiveLayout() { return realPresenter.getPerspective(); } + } diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest5.expected b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest5.expected index 3bbe92cb0d..20a4a01612 100644 --- a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest5.expected +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest5.expected @@ -61,4 +61,5 @@ public class PerspectiveTest5Activity extends AbstractWorkbenchPerspectiveActivi public PerspectiveDefinition getDefaultPerspectiveLayout() { return realPresenter.getPerspective(); } + } diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest6.expected b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest6.expected index 5ebf3afc5a..146ed18d2c 100644 --- a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest6.expected +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest6.expected @@ -79,4 +79,5 @@ public class PerspectiveTest6Activity extends AbstractWorkbenchPerspectiveActivi public PerspectiveDefinition getDefaultPerspectiveLayout() { return realPresenter.getPerspective(); } + } diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest7.expected b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest7.expected index 85fd04d646..ed014c50e5 100644 --- a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest7.expected +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest7.expected @@ -79,4 +79,5 @@ public class PerspectiveTest7Activity extends AbstractWorkbenchPerspectiveActivi public PerspectiveDefinition getDefaultPerspectiveLayout() { return realPresenter.getPerspective(); } + } diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest8.expected b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest8.expected index 306a3647fa..ed010c1bd3 100644 --- a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest8.expected +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest8.expected @@ -63,4 +63,5 @@ public class PerspectiveTest8Activity extends AbstractWorkbenchPerspectiveActivi public Menus getMenus() { return realPresenter.getMenus(); } + } diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest9.expected b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest9.expected index 1b895ef9bc..c28ef7f461 100644 --- a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest9.expected +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/PerspectiveTest9.expected @@ -56,4 +56,5 @@ public class PerspectiveTest9Activity extends AbstractWorkbenchPerspectiveActivi public PerspectiveDefinition getDefaultPerspectiveLayout() { return realPresenter.getPerspective(); } + } diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchEditorTest22.expected b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchEditorTest22.expected index 42efb60958..b265f40a7a 100644 --- a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchEditorTest22.expected +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchEditorTest22.expected @@ -58,12 +58,12 @@ public class WorkbenchEditorTest22Activity extends AbstractWorkbenchEditorActivi } @Override - public Integer preferredHeight() { + public int preferredHeight() { return 200; } @Override - public Integer preferredWidth() { + public int preferredWidth() { return 300; } diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchEditorTest24.expected b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchEditorTest24.expected index 9995a662f8..a02196fee9 100644 --- a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchEditorTest24.expected +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchEditorTest24.expected @@ -58,7 +58,7 @@ public class WorkbenchEditorTest24Activity extends AbstractWorkbenchEditorActivi } @Override - public Integer preferredWidth() { + public int preferredWidth() { return 200; } diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchEditorTest26.expected b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchEditorTest26.expected index 1a882dab10..5346ce5522 100644 --- a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchEditorTest26.expected +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchEditorTest26.expected @@ -58,7 +58,7 @@ public class WorkbenchEditorTest26Activity extends AbstractWorkbenchEditorActivi } @Override - public Integer preferredHeight() { + public int preferredHeight() { return 200; } diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchEditorTest28.expected b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchEditorTest28.expected new file mode 100644 index 0000000000..e295d6368f --- /dev/null +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchEditorTest28.expected @@ -0,0 +1,92 @@ +/* + * 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.uberfire.annotations.processors; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import javax.annotation.Generated; +import javax.enterprise.context.Dependent; +import javax.inject.Inject; + +import javax.inject.Named; +import org.uberfire.client.workbench.annotations.AssociatedResources; +import org.uberfire.client.workbench.annotations.Priority; +import org.uberfire.client.mvp.AbstractWorkbenchEditorActivity; +import org.uberfire.client.mvp.PlaceManager; + +import org.uberfire.mvp.PlaceRequest; + +import org.uberfire.backend.vfs.ObservablePath; + +import com.google.gwt.user.client.ui.IsWidget; + +import jsinterop.annotations.JsIgnore; +import jsinterop.annotations.JsType; +import org.jboss.errai.ioc.client.api.Shared; + +@Dependent +@Generated("org.uberfire.annotations.processors.WorkbenchEditorProcessor") +@Named("test28") +@AssociatedResources({ + org.uberfire.client.mvp.MyTestType.class +}) + +@Priority(0) +@JsType +/* + * WARNING! This class is generated. Do not modify. + */ +public class WorkbenchEditorTest28Activity extends AbstractWorkbenchEditorActivity { + + @Inject + private WorkbenchEditorTest28 realPresenter; + + @Inject + //Constructor injection for testing + public WorkbenchEditorTest28Activity(@Shared final PlaceManager placeManager) { + super( placeManager ); + } + + @JsIgnore @Override + public void onStartup(final ObservablePath path, + final PlaceRequest place) { + super.onStartup( path, place ); + realPresenter.onStartup( path ); + } + + @Override + public String getTitle() { + return realPresenter.getTitle(); + } + + @JsIgnore @Override + public IsWidget getWidget() { + return realPresenter.getView(); + } + + @Override + public String getIdentifier() { + return "test28"; + } + + @Override + public boolean isDynamic() { + return true; + } + +} diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchScreenTest24.expected b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchScreenTest24.expected index d106f1aa98..daa7f896c3 100644 --- a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchScreenTest24.expected +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchScreenTest24.expected @@ -50,7 +50,7 @@ public class WorkbenchScreenTest24Activity extends AbstractWorkbenchScreenActivi } @Override - public Integer preferredWidth() { + public int preferredWidth() { return 200; } diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchScreenTest26.expected b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchScreenTest26.expected index 65a3d0dcf4..33a9391707 100644 --- a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchScreenTest26.expected +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchScreenTest26.expected @@ -50,7 +50,7 @@ public class WorkbenchScreenTest26Activity extends AbstractWorkbenchScreenActivi } @Override - public Integer preferredHeight() { + public int preferredHeight() { return 200; } diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchScreenTest28.expected b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchScreenTest28.expected index d552913a1e..8b33b64e17 100644 --- a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchScreenTest28.expected +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchScreenTest28.expected @@ -50,12 +50,12 @@ public class WorkbenchScreenTest28Activity extends AbstractWorkbenchScreenActivi } @Override - public Integer preferredHeight() { + public int preferredHeight() { return 300; } @Override - public Integer preferredWidth() { + public int preferredWidth() { return 200; } diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchScreenTest29.expected b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchScreenTest29.expected index 1fa8d96db2..1e90a6848d 100644 --- a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchScreenTest29.expected +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchScreenTest29.expected @@ -64,4 +64,4 @@ public class WorkbenchScreenTest29Activity extends AbstractWorkbenchScreenActivi public String getIdentifier() { return "test29"; } -} +} \ No newline at end of file diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchScreenTest33.expected b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchScreenTest33.expected new file mode 100644 index 0000000000..241e8a7c67 --- /dev/null +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchScreenTest33.expected @@ -0,0 +1,90 @@ +/* + * 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.uberfire.annotations.processors; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import javax.annotation.Generated; +import javax.enterprise.context.Dependent; +import javax.inject.Inject; +import com.google.gwt.user.client.ui.InlineLabel; + +import javax.annotation.PostConstruct; +import org.uberfire.client.mvp.UberView; + +import javax.inject.Named; +import org.uberfire.client.mvp.AbstractWorkbenchScreenActivity; +import org.uberfire.client.mvp.PlaceManager; + +import org.uberfire.mvp.PlaceRequest; + +import com.google.gwt.user.client.ui.IsWidget; + +import jsinterop.annotations.JsIgnore; +import jsinterop.annotations.JsType; +import org.jboss.errai.ioc.client.api.Shared; + +@Dependent +@Generated("org.uberfire.annotations.processors.WorkbenchScreenProcessor") +@Named("test33") +@JsType +/* + * WARNING! This class is generated. Do not modify. + */ +public class WorkbenchScreenTest33Activity extends AbstractWorkbenchScreenActivity { + + @Inject + private WorkbenchScreenTest33 realPresenter; + + @Inject + //Constructor injection for testing + public WorkbenchScreenTest33Activity(@Shared final PlaceManager placeManager) { + super( placeManager ); + } + + @PostConstruct + public void init() { + ((UberView) realPresenter.getView()).init( realPresenter ); + } + + @Override + public void onStartup(final PlaceRequest place) { + super.onStartup( place ); + realPresenter.onStartup(); + } + + @Override + public String getTitle() { + return realPresenter.getTitle(); + } + + @JsIgnore @Override + public IsWidget getWidget() { + return realPresenter.getView(); + } + + @Override + public String getIdentifier() { + return "test33"; + } + + @Override + public boolean isDynamic() { + return true; + } +} \ No newline at end of file diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchSplashScreenTest6.expected b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchSplashScreenTest6.expected index 8dbecb25ee..ec2c3a5784 100644 --- a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchSplashScreenTest6.expected +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchSplashScreenTest6.expected @@ -76,4 +76,5 @@ public class WorkbenchSplashScreenTest6Activity extends AbstractSplashScreenActi public String getIdentifier() { return "test6"; } + } diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchSplashScreenTest7.expected b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchSplashScreenTest7.expected index 88d9828055..c3e2c7e02c 100644 --- a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchSplashScreenTest7.expected +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchSplashScreenTest7.expected @@ -79,4 +79,5 @@ public class WorkbenchSplashScreenTest7Activity extends AbstractSplashScreenActi public String getIdentifier() { return "test7"; } + } diff --git a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchSplashScreenTest9.expected b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchSplashScreenTest9.expected index 823c6362a1..8ec5277e96 100644 --- a/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchSplashScreenTest9.expected +++ b/uberfire-workbench/uberfire-workbench-processors-tests/src/test/resources/org/uberfire/annotations/processors/expected/WorkbenchSplashScreenTest9.expected @@ -79,4 +79,5 @@ public class WorkbenchSplashScreenTest9Activity extends AbstractSplashScreenActi public String getIdentifier() { return "test9"; } + } diff --git a/uberfire-workbench/uberfire-workbench-processors/src/main/java/org/uberfire/annotations/processors/EditorActivityGenerator.java b/uberfire-workbench/uberfire-workbench-processors/src/main/java/org/uberfire/annotations/processors/EditorActivityGenerator.java index b8351f3e31..9cb7f50401 100644 --- a/uberfire-workbench/uberfire-workbench-processors/src/main/java/org/uberfire/annotations/processors/EditorActivityGenerator.java +++ b/uberfire-workbench/uberfire-workbench-processors/src/main/java/org/uberfire/annotations/processors/EditorActivityGenerator.java @@ -31,7 +31,6 @@ import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; -import javax.lang.model.util.Elements; import javax.tools.Diagnostic.Kind; import org.uberfire.annotations.processors.exceptions.GenerationException; @@ -55,13 +54,11 @@ public StringBuffer generate( final String packageName, final Messager messager = processingEnvironment.getMessager(); messager.printMessage( Kind.NOTE, "Starting code generation for [" + className + "]" ); - final Elements elementUtils = processingEnvironment.getElementUtils(); - //Extract required information final TypeElement classElement = (TypeElement) element; final String annotationName = ClientAPIModule.getWorkbenchEditorClass(); - + final boolean isDynamic = ClientAPIModule.getWbEditorIsDynamicValueOnClass( classElement ); final String owningPlace = GeneratorUtils.getOwningPerspectivePlaceRequest( classElement, processingEnvironment ); Integer priority = 0; @@ -274,6 +271,8 @@ public StringBuffer generate( final String packageName, getMenuBarMethodName ); root.put( "getToolBarMethodName", getToolBarMethodName ); + root.put( "isDynamic", + isDynamic ); //Generate code final StringWriter sw = new StringWriter(); diff --git a/uberfire-workbench/uberfire-workbench-processors/src/main/java/org/uberfire/annotations/processors/PerspectiveActivityGenerator.java b/uberfire-workbench/uberfire-workbench-processors/src/main/java/org/uberfire/annotations/processors/PerspectiveActivityGenerator.java index 945c96f9d7..81ada1288b 100644 --- a/uberfire-workbench/uberfire-workbench-processors/src/main/java/org/uberfire/annotations/processors/PerspectiveActivityGenerator.java +++ b/uberfire-workbench/uberfire-workbench-processors/src/main/java/org/uberfire/annotations/processors/PerspectiveActivityGenerator.java @@ -62,6 +62,7 @@ public StringBuffer generate( final String packageName, String identifier = ClientAPIModule.getWbPerspectiveScreenIdentifierValueOnClass( classElement ); boolean isDefault = ClientAPIModule.getWbPerspectiveScreenIsDefaultValueOnClass( classElement ); boolean isTransient = ClientAPIModule.getWbPerspectiveScreenIsTransientValueOnClass( classElement ); + boolean isDynamic = ClientAPIModule.getWbPerspectiveScreenIsDynamicValueOnClass( classElement ); final String beanActivatorClass = GeneratorUtils.getBeanActivatorClassName( classElement, processingEnvironment ); @@ -161,6 +162,8 @@ public StringBuffer generate( final String packageName, getMenuBarMethodName ); root.put( "getToolBarMethodName", getToolBarMethodName ); + root.put( "isDynamic", + isDynamic ); //Generate code final StringWriter sw = new StringWriter(); diff --git a/uberfire-workbench/uberfire-workbench-processors/src/main/java/org/uberfire/annotations/processors/ScreenActivityGenerator.java b/uberfire-workbench/uberfire-workbench-processors/src/main/java/org/uberfire/annotations/processors/ScreenActivityGenerator.java index 96869bf5a3..97d330f3dc 100644 --- a/uberfire-workbench/uberfire-workbench-processors/src/main/java/org/uberfire/annotations/processors/ScreenActivityGenerator.java +++ b/uberfire-workbench/uberfire-workbench-processors/src/main/java/org/uberfire/annotations/processors/ScreenActivityGenerator.java @@ -56,6 +56,7 @@ public StringBuffer generate( final String packageName, //Extract required information final TypeElement classElement = (TypeElement) element; final String annotationName = ClientAPIModule.getWorkbenchScreenClass(); + final boolean isDynamic = ClientAPIModule.getWbScreenIsDynamicValueOnClass( classElement ); String identifier = null; Integer preferredHeight = null; @@ -254,6 +255,8 @@ public StringBuffer generate( final String packageName, getMenuBarMethodName ); root.put( "getToolBarMethodName", getToolBarMethodName ); + root.put( "isDynamic", + isDynamic ); //Generate code final StringWriter sw = new StringWriter(); diff --git a/uberfire-workbench/uberfire-workbench-processors/src/main/java/org/uberfire/annotations/processors/facades/ClientAPIModule.java b/uberfire-workbench/uberfire-workbench-processors/src/main/java/org/uberfire/annotations/processors/facades/ClientAPIModule.java index 0b782d3262..194cee59e1 100644 --- a/uberfire-workbench/uberfire-workbench-processors/src/main/java/org/uberfire/annotations/processors/facades/ClientAPIModule.java +++ b/uberfire-workbench/uberfire-workbench-processors/src/main/java/org/uberfire/annotations/processors/facades/ClientAPIModule.java @@ -37,6 +37,7 @@ public class ClientAPIModule { public static final String SIZE = "size"; public static final String OWNING_PERSPECTIVE = "owningPerspective"; public static final String IS_DEFAULT = "isDefault"; + public static final String IS_DYNAMIC = "isDynamic"; public static final String IS_TRANSIENT = "isTransient"; public static final String IS_TEMPLATE = "isTemplate"; public static final String IS_ENABLED = "isEnabled"; @@ -63,6 +64,7 @@ private ClientAPIModule() { public static final String splashBodyHeight = "org.uberfire.client.annotations.SplashBodyHeight"; public static final String intercept = "org.uberfire.client.annotations.Intercept"; public static final String workbenchPanel = "org.uberfire.client.annotations.WorkbenchPanel"; + public static final String jsType = "jsinterop.annotations.JsType"; public static String getWorkbenchScreenClass() { return workbenchScreen; @@ -190,6 +192,21 @@ public static Boolean getWbPerspectiveScreenIsDefaultValueOnClass( TypeElement c String bool = ( getAnnotationStringParam( classElement, workbenchPerspective, IS_DEFAULT ) ); return Boolean.valueOf( bool ); } + + public static Boolean getWbPerspectiveScreenIsDynamicValueOnClass( TypeElement classElement ) { + String bool = ( getAnnotationStringParam( classElement, workbenchPerspective, IS_DYNAMIC ) ); + return Boolean.valueOf( bool ); + } + + public static Boolean getWbScreenIsDynamicValueOnClass( TypeElement classElement ) { + String bool = ( getAnnotationStringParam( classElement, workbenchScreen, IS_DYNAMIC ) ); + return Boolean.valueOf( bool ); + } + + public static Boolean getWbEditorIsDynamicValueOnClass( TypeElement classElement ) { + String bool = ( getAnnotationStringParam( classElement, workbenchEditor, IS_DYNAMIC ) ); + return Boolean.valueOf( bool ); + } public static Boolean getWbPerspectiveScreenIsTransientValueOnClass( TypeElement classElement ) { String bool = ( getAnnotationStringParam( classElement, workbenchPerspective, IS_TRANSIENT ) ); @@ -237,4 +254,5 @@ public static boolean isATemplate( Elements elementUtils, Element element ) { return GeneratorUtils.getAnnotation( elementUtils, element, workbenchPanel ) != null; } + } diff --git a/uberfire-workbench/uberfire-workbench-processors/src/main/resources/org/uberfire/annotations/processors/templates/activityEditor.ftl b/uberfire-workbench/uberfire-workbench-processors/src/main/resources/org/uberfire/annotations/processors/templates/activityEditor.ftl index cffd8be266..a1b4397004 100644 --- a/uberfire-workbench/uberfire-workbench-processors/src/main/resources/org/uberfire/annotations/processors/templates/activityEditor.ftl +++ b/uberfire-workbench/uberfire-workbench-processors/src/main/resources/org/uberfire/annotations/processors/templates/activityEditor.ftl @@ -65,6 +65,12 @@ import org.jboss.errai.ioc.client.api.ActivatedBy; import org.uberfire.client.annotations.WorkbenchEditor.LockingStrategy; import static org.uberfire.client.annotations.WorkbenchEditor.LockingStrategy.*; + +<#if isDynamic> +import jsinterop.annotations.JsIgnore; +import jsinterop.annotations.JsType; +import org.jboss.errai.ioc.client.api.Shared; + @Dependent @Generated("org.uberfire.annotations.processors.WorkbenchEditorProcessor") @@ -76,6 +82,9 @@ ${associatedResources} <#if beanActivatorClass??> @ActivatedBy(${beanActivatorClass}.class) +<#if isDynamic> +@JsType + /* * WARNING! This class is generated. Do not modify. */ @@ -86,144 +95,142 @@ public class ${className} extends AbstractWorkbenchEditorActivity { @Inject //Constructor injection for testing - public ${className}(final PlaceManager placeManager) { + public ${className}(<#if isDynamic>@Shared final PlaceManager placeManager) { super( placeManager ); } - <#if hasUberView> + <#if hasUberView> @PostConstruct public void init() { ((UberView) realPresenter.${getWidgetMethodName}()).init( realPresenter ); } + <#if preferredHeight??> - @Override - public Integer preferredHeight() { + public int preferredHeight() { return ${preferredHeight}; } + <#if preferredWidth??> - @Override - public Integer preferredWidth() { + public int preferredWidth() { return ${preferredWidth}; } + <#if onStartup2ParameterMethodName??> - - @Override + <#if isDynamic>@JsIgnore @Override public void onStartup(final ObservablePath path, final PlaceRequest place) { super.onStartup( path, place ); realPresenter.${onStartup2ParameterMethodName}( path, place ); } - <#elseif onStartup1ParameterMethodName??> - @Override + <#elseif onStartup1ParameterMethodName??> + <#if isDynamic>@JsIgnore @Override public void onStartup(final ObservablePath path, final PlaceRequest place) { super.onStartup( path, place ); realPresenter.${onStartup1ParameterMethodName}( path ); } + <#if onMayCloseMethodName??> - @Override public boolean onMayClose() { return realPresenter.${onMayCloseMethodName}(); } + <#if onCloseMethodName??> - @Override public void onClose() { super.onClose(); realPresenter.${onCloseMethodName}(); } + <#if onShutdownMethodName??> - @Override public void onShutdown() { super.onShutdown(); realPresenter.${onShutdownMethodName}(); } + <#if onOpenMethodName??> - @Override public void onOpen() { super.onOpen(); realPresenter.${onOpenMethodName}(); } + <#if onLostFocusMethodName??> - @Override public void onLostFocus() { super.onLostFocus(); realPresenter.${onLostFocusMethodName}(); } + <#if onFocusMethodName??> - @Override public void onFocus() { super.onFocus(); realPresenter.${onFocusMethodName}(); } + <#if owningPlace??> - @Override public PlaceRequest getOwningPlace() { return new DefaultPlaceRequest("${owningPlace}"); } + <#if getTitleWidgetMethodName??> - - @Override + <#if isDynamic>@JsIgnore @Override public IsWidget getTitleDecoration() { return realPresenter.${getTitleWidgetMethodName}(); } + <#if getTitleMethodName??> - @Override public String getTitle() { return realPresenter.${getTitleMethodName}(); } + <#if getWidgetMethodName??> - - @Override + <#if isDynamic>@JsIgnore @Override public IsWidget getWidget() { return realPresenter.${getWidgetMethodName}(); } - <#elseif isWidget> - @Override + <#elseif isWidget> + <#if isDynamic>@JsIgnore @Override public IsWidget getWidget() { return realPresenter; } + <#if getDefaultPositionMethodName??> - @Override public Position getDefaultPosition() { return realPresenter.${getDefaultPositionMethodName}(); } <#if isDirtyMethodName??> - @Override public boolean isDirty() { return realPresenter.${isDirtyMethodName}(); } <#if onSaveMethodName??> - @Override public void onSave() { super.onSave(); @@ -231,36 +238,43 @@ public class ${className} extends AbstractWorkbenchEditorActivity { } <#if getMenuBarMethodName??> - @Override public Menus getMenus() { return realPresenter.${getMenuBarMethodName}(); } + <#if getToolBarMethodName??> - @Override public ToolBar getToolBar() { return realPresenter.${getToolBarMethodName}(); } + <#if getContextIdMethodName??> - @Override public String contextId() { return realPresenter.${getContextIdMethodName}(); } + <#if lockingStrategy??> - @Override public LockingStrategy getLockingStrategy() { return ${lockingStrategy}; } - + @Override public String getIdentifier() { return "${identifier}"; } + <#if isDynamic> + + @Override + public boolean isDynamic() { + return true; + } + + } diff --git a/uberfire-workbench/uberfire-workbench-processors/src/main/resources/org/uberfire/annotations/processors/templates/activityScreen.ftl b/uberfire-workbench/uberfire-workbench-processors/src/main/resources/org/uberfire/annotations/processors/templates/activityScreen.ftl index 040caa2582..e7a3e6cab2 100644 --- a/uberfire-workbench/uberfire-workbench-processors/src/main/resources/org/uberfire/annotations/processors/templates/activityScreen.ftl +++ b/uberfire-workbench/uberfire-workbench-processors/src/main/resources/org/uberfire/annotations/processors/templates/activityScreen.ftl @@ -63,6 +63,12 @@ import com.google.gwt.user.client.ui.IsWidget; <#if beanActivatorClass??> import org.jboss.errai.ioc.client.api.ActivatedBy; + +<#if isDynamic> +import jsinterop.annotations.JsIgnore; +import jsinterop.annotations.JsType; +import org.jboss.errai.ioc.client.api.Shared; + @Dependent @Generated("org.uberfire.annotations.processors.WorkbenchScreenProcessor") @@ -70,6 +76,9 @@ import org.jboss.errai.ioc.client.api.ActivatedBy; <#if beanActivatorClass??> @ActivatedBy(${beanActivatorClass}.class) +<#if isDynamic> +@JsType + /* * WARNING! This class is generated. Do not modify. */ @@ -80,7 +89,7 @@ public class ${className} extends AbstractWorkbenchScreenActivity { @Inject //Constructor injection for testing - public ${className}(final PlaceManager placeManager) { + public ${className}(<#if isDynamic>@Shared final PlaceManager placeManager) { super( placeManager ); } <#if hasUberView> @@ -100,14 +109,14 @@ public class ${className} extends AbstractWorkbenchScreenActivity { <#if preferredHeight??> @Override - public Integer preferredHeight() { + public int preferredHeight() { return ${preferredHeight}; } <#if preferredWidth??> @Override - public Integer preferredWidth() { + public int preferredWidth() { return ${preferredWidth}; } @@ -182,7 +191,7 @@ public class ${className} extends AbstractWorkbenchScreenActivity { <#if getTitleWidgetMethodName??> - @Override + <#if isDynamic>@JsIgnore @Override public IsWidget getTitleDecoration() { <#if isTitleWidgetMethodReturnTypeElement> return ElementWrapperWidget.getWidget( realPresenter.${getTitleWidgetMethodName}().getElement() ); @@ -197,10 +206,10 @@ public class ${className} extends AbstractWorkbenchScreenActivity { public String getTitle() { return realPresenter.${getTitleMethodName}(); } + <#if getWidgetMethodName??> - - @Override + <#if isDynamic>@JsIgnore @Override public IsWidget getWidget() { <#if isWidgetMethodReturnTypeElement> return ElementWrapperWidget.getWidget( realPresenter.${getWidgetMethodName}().getElement() ); @@ -208,12 +217,13 @@ public class ${className} extends AbstractWorkbenchScreenActivity { return realPresenter.${getWidgetMethodName}(); } - <#elseif isWidget> - @Override + <#elseif isWidget> + <#if isDynamic>@JsIgnore @Override public IsWidget getWidget() { return realPresenter; } + <#if getDefaultPositionMethodName??> @@ -223,18 +233,18 @@ public class ${className} extends AbstractWorkbenchScreenActivity { } <#if getMenuBarMethodName??> - @Override public Menus getMenus() { return realPresenter.${getMenuBarMethodName}(); } + <#if getToolBarMethodName??> - @Override public ToolBar getToolBar() { return realPresenter.${getToolBarMethodName}(); } + <#if getContextIdMethodName??> @@ -243,9 +253,15 @@ public class ${className} extends AbstractWorkbenchScreenActivity { return realPresenter.${getContextIdMethodName}(); } - @Override public String getIdentifier() { return "${identifier}"; } + <#if isDynamic> + + @Override + public boolean isDynamic() { + return true; + } + } diff --git a/uberfire-workbench/uberfire-workbench-processors/src/main/resources/org/uberfire/annotations/processors/templates/perspective.ftl b/uberfire-workbench/uberfire-workbench-processors/src/main/resources/org/uberfire/annotations/processors/templates/perspective.ftl index 244b6e2e3a..541cb99ce5 100644 --- a/uberfire-workbench/uberfire-workbench-processors/src/main/resources/org/uberfire/annotations/processors/templates/perspective.ftl +++ b/uberfire-workbench/uberfire-workbench-processors/src/main/resources/org/uberfire/annotations/processors/templates/perspective.ftl @@ -60,6 +60,11 @@ import org.uberfire.workbench.model.impl.PartDefinitionImpl; <#if beanActivatorClass??> import org.jboss.errai.ioc.client.api.ActivatedBy; + +<#if isDynamic> +import jsinterop.annotations.JsType; +import org.jboss.errai.ioc.client.api.Shared; + @Dependent @Generated("org.uberfire.annotations.processors.WorkbenchPerspectiveProcessor") @@ -67,6 +72,9 @@ import org.jboss.errai.ioc.client.api.ActivatedBy; <#if beanActivatorClass??> @ActivatedBy(${beanActivatorClass}.class) +<#if isDynamic> +@JsType + /* * WARNING! This class is generated. Do not modify. */ @@ -77,7 +85,7 @@ public class ${className} extends AbstractWorkbenchPerspectiveActivity<#if isTem @Inject //Constructor injection for testing - public ${className}(final PlaceManager placeManager) { + public ${className}(<#if isDynamic>@Shared final PlaceManager placeManager) { super( placeManager ); } @@ -85,82 +93,81 @@ public class ${className} extends AbstractWorkbenchPerspectiveActivity<#if isTem public String getIdentifier() { return "${identifier}"; } -<#if isDefault> +<#if isDefault> @Override public boolean isDefault() { return true; } + <#if !isTransient> - @Override public boolean isTransient() { return false; } + <#if onStartup1ParameterMethodName??> - @Override public void onStartup(final PlaceRequest place) { super.onStartup( place ); realPresenter.${onStartup1ParameterMethodName}( place ); } -<#elseif onStartup0ParameterMethodName??> +<#elseif onStartup0ParameterMethodName??> @Override public void onStartup(final PlaceRequest place) { super.onStartup( place ); realPresenter.${onStartup0ParameterMethodName}(); } + <#if onCloseMethodName??> - @Override public void onClose() { super.onClose(); realPresenter.${onCloseMethodName}(); } + <#if onShutdownMethodName??> - @Override public void onShutdown() { super.onShutdown(); realPresenter.${onShutdownMethodName}(); } + <#if onOpenMethodName??> - @Override public void onOpen() { super.onOpen(); realPresenter.${onOpenMethodName}(); } + <#if getPerspectiveMethodName??> - @Override public PerspectiveDefinition getDefaultPerspectiveLayout() { return realPresenter.${getPerspectiveMethodName}(); } + <#if getMenuBarMethodName??> - @Override public Menus getMenus() { return realPresenter.${getMenuBarMethodName}(); } + <#if getToolBarMethodName??> - @Override public ToolBar getToolBar() { return realPresenter.${getToolBarMethodName}(); - } + } <#if isTemplate> - @Override public IsWidget getRootWidget() { return realPresenter; @@ -225,4 +232,10 @@ public class ${className} extends AbstractWorkbenchPerspectiveActivity<#if isTem return p; } +<#if isDynamic> + @Override + public boolean isDynamic() { + return true; + } + } diff --git a/uberfire-workbench/uberfire-workbench-processors/src/main/resources/org/uberfire/annotations/processors/templates/popupScreen.ftl b/uberfire-workbench/uberfire-workbench-processors/src/main/resources/org/uberfire/annotations/processors/templates/popupScreen.ftl index 1ffaa960c7..4dcc7bb384 100644 --- a/uberfire-workbench/uberfire-workbench-processors/src/main/resources/org/uberfire/annotations/processors/templates/popupScreen.ftl +++ b/uberfire-workbench/uberfire-workbench-processors/src/main/resources/org/uberfire/annotations/processors/templates/popupScreen.ftl @@ -64,87 +64,87 @@ public class ${className} extends AbstractPopupActivity { public ${className}( final PlaceManager placeManager, final PopupView view ) { super( placeManager, view ); } - <#if hasUberView> + <#if hasUberView> @PostConstruct public void init() { ((UberView) realPresenter.${getWidgetMethodName}()).init( realPresenter ); } + <#if onStartup1ParameterMethodName??> - @Override public void onStartup(final PlaceRequest place) { super.onStartup( place ); realPresenter.${onStartup1ParameterMethodName}( place ); } - <#elseif onStartup0ParameterMethodName??> + <#elseif onStartup0ParameterMethodName??> @Override public void onStartup(final PlaceRequest place) { super.onStartup( place ); realPresenter.${onStartup0ParameterMethodName}(); } + <#if onMayCloseMethodName??> - @Override public boolean onMayClose() { return realPresenter.${onMayCloseMethodName}(); } + <#if onCloseMethodName??> - @Override public void onClose() { super.onClose(); realPresenter.${onCloseMethodName}(); } + <#if onShutdownMethodName??> - @Override public void onShutdown() { super.onShutdown(); realPresenter.${onShutdownMethodName}(); } + <#if onOpenMethodName??> - @Override public void onOpen() { super.onOpen(); realPresenter.${onOpenMethodName}(); } + <#if getTitleWidgetMethodName??> - @Override public IsWidget getTitleDecoration() { return realPresenter.${getTitleWidgetMethodName}(); } + <#if getTitleMethodName??> - @Override public String getTitle() { return realPresenter.${getTitleMethodName}(); } + <#if getWidgetMethodName??> - @Override public IsWidget getWidget() { return realPresenter.${getWidgetMethodName}(); } - <#elseif isWidget> + <#elseif isWidget> @Override public IsWidget getWidget() { return realPresenter; } - + @Override public String getIdentifier() { return "${identifier}"; diff --git a/uberfire-workbench/uberfire-workbench-processors/src/main/resources/org/uberfire/annotations/processors/templates/splashScreen.ftl b/uberfire-workbench/uberfire-workbench-processors/src/main/resources/org/uberfire/annotations/processors/templates/splashScreen.ftl index 5d869c848b..81743f373c 100644 --- a/uberfire-workbench/uberfire-workbench-processors/src/main/resources/org/uberfire/annotations/processors/templates/splashScreen.ftl +++ b/uberfire-workbench/uberfire-workbench-processors/src/main/resources/org/uberfire/annotations/processors/templates/splashScreen.ftl @@ -63,35 +63,36 @@ public class ${className} extends AbstractSplashScreenActivity { public ${className}( final PlaceManager placeManager, final SplashView view ) { super( placeManager, view ); } - <#if hasUberView> + <#if hasUberView> @PostConstruct public void init() { ((UberView) realPresenter.${getWidgetMethodName}()).init( realPresenter ); } + <#if onStartup1ParameterMethodName??> - @Override public void onStartup(final PlaceRequest place) { super.onStartup( place ); realPresenter.${onStartup1ParameterMethodName}( place ); } - <#elseif onStartup0ParameterMethodName??> + <#elseif onStartup0ParameterMethodName??> @Override public void onStartup(final PlaceRequest place) { super.onStartup( place ); realPresenter.${onStartup0ParameterMethodName}(); } + <#if onCloseMethodName??> - @Override public void onClose() { realPresenter.${onCloseMethodName}(); super.onClose(); } + <#if onShutdownMethodName??> @Override @@ -99,6 +100,7 @@ public class ${className} extends AbstractSplashScreenActivity { super.onShutdown(); realPresenter.${onShutdownMethodName}(); } + <#if onOpenMethodName??> @Override @@ -106,55 +108,56 @@ public class ${className} extends AbstractSplashScreenActivity { super.onOpen(); realPresenter.${onOpenMethodName}(); } + <#if getTitleWidgetMethodName??> - @Override public IsWidget getTitleDecoration() { return realPresenter.${getTitleWidgetMethodName}(); } + <#if getTitleMethodName??> - @Override public String getTitle() { return realPresenter.${getTitleMethodName}(); } + <#if getWidgetMethodName??> - @Override public IsWidget getWidget() { return realPresenter.${getWidgetMethodName}(); } + <#elseif isWidget> @Override public IsWidget getWidget() { return realPresenter; } + <#if getBodyHeightMethodName??> - @Override public Integer getBodyHeight() { return realPresenter.${getBodyHeightMethodName}(); } + <#if getSplashFilterMethodName??> - @Override public SplashScreenFilter getFilter() { return realPresenter.${getSplashFilterMethodName}(); } + <#if getInterceptMethodName??> - @Override public Boolean intercept( final PlaceRequest intercepted ) { return realPresenter.${getInterceptMethodName}( intercepted ); } - + @Override public boolean isEnabled() { <#if isEnabled> @@ -168,4 +171,5 @@ public class ${className} extends AbstractSplashScreenActivity { public String getIdentifier() { return "${identifier}"; } + }