You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2022/10/10 12:16:02 UTC
[syncope] branch master updated: [SYNCOPE-1697] Command and Macro introduced (#378)
This is an automated email from the ASF dual-hosted git repository.
ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git
The following commit(s) were added to refs/heads/master by this push:
new 782cb9c147 [SYNCOPE-1697] Command and Macro introduced (#378)
782cb9c147 is described below
commit 782cb9c1479bc00a57cb9ef14757b930af4011ff
Author: Francesco Chicchiriccò <il...@users.noreply.github.com>
AuthorDate: Mon Oct 10 14:15:57 2022 +0200
[SYNCOPE-1697] Command and Macro introduced (#378)
---
.../authprofiles/AuthProfileDirectoryPanel.java | 344 +++++++++++----------
.../AuthProfileItemDirectoryPanel.java | 8 +-
.../clientapps/ClientAppDirectoryPanel.java | 14 +-
...irectoryPanelAdditionalActionLinksProvider.java | 46 ++-
.../console/panels/ResourceDirectoryPanel.java | 19 +-
.../console/status/AnyStatusDirectoryPanel.java | 87 +++---
.../client/console/status/AnyStatusModal.java | 7 +-
.../status/ResourceStatusDirectoryPanel.java | 47 ++-
.../client/console/status/ResourceStatusModal.java | 9 +-
.../syncope/client/console/status/StatusModal.java | 9 +-
.../client/console/topology/TabularTopology.java | 28 +-
.../console/topology/TopologyTogglePanel.java | 36 +--
.../console/topology/TopologyTogglePanel.html | 3 -
.../topology/TopologyTogglePanel.properties | 2 -
.../topology/TopologyTogglePanel_fr_CA.properties | 17 +-
.../topology/TopologyTogglePanel_it.properties | 2 -
.../topology/TopologyTogglePanel_ja.properties | 2 -
.../topology/TopologyTogglePanel_pt_BR.properties | 2 -
.../topology/TopologyTogglePanel_ru.properties | 2 -
.../client/console/audit/AuditHistoryDetails.java | 38 +--
.../client/console/audit/AuditHistoryModal.java | 2 +-
.../client/console/commons/IdRepoConstants.java | 2 +
.../commons/IdRepoImplementationInfoProvider.java | 6 +-
.../KeywordSearchEvent.java} | 27 +-
.../commons/LinkedAccountPlainAttrProperty.java | 14 +-
.../console/notifications/NotificationTasks.java | 5 +-
.../syncope/client/console/pages/BasePage.java | 89 +++---
.../pages/{Reports.java => Engagements.java} | 48 ++-
.../syncope/client/console/pages/Reports.java | 5 +-
.../console/panels/AccessTokenDirectoryPanel.java | 7 +-
.../client/console/panels/AjaxDataTablePanel.java | 7 +-
.../console/panels/CommandDirectoryPanel.java | 190 ++++++++++++
.../{SchemasPanel.java => CommandsPanel.java} | 42 +--
.../console/panels/DashboardAccessTokensPanel.java | 8 +-
.../client/console/panels/ExecMessageModal.java | 1 -
.../console/panels/ImplementationModalPanel.java | 4 +-
.../client/console/panels/ModalDirectoryPanel.java | 2 +-
.../client/console/panels/SchemaTypePanel.java | 67 ++--
.../client/console/panels/SchemasPanel.java | 4 +-
.../console/policies/PolicyRuleDirectoryPanel.java | 21 +-
.../console/policies/PolicyRuleWizardBuilder.java | 5 +-
.../console/reports/ReportDirectoryPanel.java | 58 ++--
.../console/reports/ReportExecutionDetails.java | 19 +-
.../console/reports/ReportletDirectoryPanel.java | 43 +--
.../console/reports/ReportletWizardBuilder.java | 69 +++--
.../client/console/rest/AccessTokenRestClient.java | 1 -
.../client/console/rest/CommandRestClient.java | 50 +++
.../client/console/rest/TaskRestClient.java | 47 ++-
.../client/console/tasks/AnyPropagationTasks.java | 4 +-
.../tasks/CommandComposeDirectoryPanel.java | 234 ++++++++++++++
.../console/tasks/CommandComposeWizardBuilder.java | 161 ++++++++++
.../{ExecMessage.java => CommandWrapper.java} | 36 ++-
.../syncope/client/console/tasks/ExecMessage.java | 9 +
.../console/tasks/ExecutionsDirectoryPanel.java | 28 +-
.../console/tasks/MacroTaskDirectoryPanel.java | 88 ++++++
.../tasks/NotificationTaskDirectoryPanel.java | 7 +-
.../tasks/PropagationTaskDirectoryPanel.java | 10 +-
.../client/console/tasks/PropagationTasks.java | 20 +-
.../tasks/ProvisioningTaskDirectoryPanel.java | 88 +-----
.../console/tasks/PullTaskDirectoryPanel.java | 4 +-
.../syncope/client/console/tasks/PullTasks.java | 10 +-
.../console/tasks/PushTaskDirectoryPanel.java | 4 +-
.../syncope/client/console/tasks/PushTasks.java | 12 +-
.../console/tasks/SchedTaskDirectoryPanel.java | 200 +++++-------
.../console/tasks/SchedTaskWizardBuilder.java | 67 +++-
.../syncope/client/console/tasks/SchedTasks.java | 76 -----
.../client/console/tasks/TaskDirectoryPanel.java | 40 ++-
.../client/console/tasks/TaskExecutionDetails.java | 8 +-
.../markup/html/form/ActionLinksTogglePanel.java | 6 +
.../wicket/markup/html/form/ConfirmBehavior.java | 8 +
.../syncope/client/console/widgets/JobWidget.java | 51 +--
.../console/wizards/CommandWizardBuilder.java | 66 ++++
.../client/console/wizards/WizardMgtPanel.java | 12 +-
.../META-INF/resources/css/syncopeConsole.scss | 9 +-
.../console/SyncopeWebApplication.properties | 2 +
.../console/SyncopeWebApplication_fr_CA.properties | 1 +
.../console/SyncopeWebApplication_it.properties | 2 +
.../console/SyncopeWebApplication_ja.properties | 2 +
.../console/SyncopeWebApplication_pt_BR.properties | 2 +
.../console/SyncopeWebApplication_ru.properties | 2 +
...yRecipientsProvider.groovy => MyCommand.groovy} | 15 +-
.../console/implementations/MyLogicActions.groovy | 2 +-
.../implementations/MyRecipientsProvider.groovy | 4 +-
.../syncope/client/console/pages/BasePage.html | 1 +
.../syncope/client/console/pages/Engagements.html | 47 +++
.../{Reports.properties => Engagements.properties} | 8 +-
...rts.properties => Engagements_fr_CA.properties} | 8 +-
..._pt_BR.properties => Engagements_it.properties} | 8 +-
...eports.properties => Engagements_ja.properties} | 8 +-
..._BR.properties => Engagements_pt_BR.properties} | 8 +-
...eports.properties => Engagements_ru.properties} | 8 +-
.../client/console/pages/Reports.properties | 2 +-
.../client/console/pages/Reports_it.properties | 2 +-
.../client/console/pages/Reports_ja.properties | 2 +-
.../client/console/pages/Reports_pt_BR.properties | 2 +-
.../client/console/pages/Reports_ru.properties | 3 +-
.../client/console/panels/CommandsPanel.html | 36 +++
.../CommandComposeWizardBuilder$CommandArgs.html | 23 ++
.../tasks/CommandComposeWizardBuilder$Profile.html | 26 ++
...CommandComposeWizardBuilder$Profile.properties} | 4 +-
...dComposeWizardBuilder$Profile_fr_CA.properties} | 4 +-
...mandComposeWizardBuilder$Profile_it.properties} | 4 +-
...mandComposeWizardBuilder$Profile_ja.properties} | 4 +-
...dComposeWizardBuilder$Profile_pt_BR.properties} | 4 +-
...mandComposeWizardBuilder$Profile_ru.properties} | 4 +-
.../MacroTaskDirectoryPanel.properties} | 6 +-
.../MacroTaskDirectoryPanel_fr_CA.properties} | 6 +-
.../MacroTaskDirectoryPanel_it.properties} | 6 +-
.../MacroTaskDirectoryPanel_ja.properties} | 6 +-
.../MacroTaskDirectoryPanel_pt_BR.properties} | 6 +-
.../MacroTaskDirectoryPanel_ru.properties} | 6 +-
.../tasks/SchedTaskDirectoryPanel.properties | 1 +
.../tasks/SchedTaskDirectoryPanel_fr_CA.properties | 11 +-
.../tasks/SchedTaskDirectoryPanel_it.properties | 1 +
.../tasks/SchedTaskDirectoryPanel_ja.properties | 1 +
.../tasks/SchedTaskDirectoryPanel_pt_BR.properties | 1 +
.../tasks/SchedTaskDirectoryPanel_ru.properties | 1 +
.../tasks/SchedTaskWizardBuilder$Profile.html | 6 +
...SchedTaskWizardBuilder$Profile_fr_CA.properties | 20 +-
.../wizards/CommandWizardBuilder$CommandArgs.html | 23 ++
.../syncope/common/lib/command/CommandArgs.java | 18 +-
.../syncope/common/lib/command/CommandOutput.java | 66 ++++
.../syncope/common/lib/command/CommandTO.java | 77 +++++
.../apache/syncope/common/lib/to/MacroTaskTO.java | 113 +++++++
.../apache/syncope/common/lib/to/SchedTaskTO.java | 4 +-
.../common/lib/types/ClientExceptionType.java | 3 +-
.../common/lib/types/IdRepoEntitlement.java | 2 +
.../common/lib/types/IdRepoImplementationType.java | 5 +-
.../apache/syncope/common/lib/types/TaskType.java | 6 +-
.../common/rest/api/beans/CommandQuery.java | 55 ++++
.../common/rest/api/service/CommandService.java | 80 +++++
.../common/rest/api/service/JAXRSService.java | 2 +
.../syncope/core/logic/AbstractAnyLogic.java | 2 +-
.../apache/syncope/core/logic/AnyObjectLogic.java | 2 +-
.../apache/syncope/core/logic/CommandLogic.java | 130 ++++++++
.../org/apache/syncope/core/logic/GroupLogic.java | 2 +-
.../syncope/core/logic/IdRepoLogicContext.java | 24 +-
.../syncope/core/logic/ImplementationLogic.java | 4 +
.../org/apache/syncope/core/logic/RealmLogic.java | 41 ++-
.../org/apache/syncope/core/logic/TaskLogic.java | 114 ++++++-
.../org/apache/syncope/core/logic/UserLogic.java | 2 +-
.../apache/syncope/core/logic/api/Command.java} | 18 +-
.../syncope/core/logic}/api/LogicActions.java | 2 +-
.../init/ClassPathScanImplementationLookup.java | 7 +-
.../core/logic/job/MacroRunJobDelegate.java | 92 ++++++
.../core/rest/cxf/IdRepoRESTCXFContext.java | 9 +
.../core/rest/cxf/service/CommandServiceImpl.java | 56 ++++
.../persistence/api/dao/ImplementationDAO.java | 2 +
.../syncope/core/persistence/api/dao/TaskDAO.java | 6 +
.../core/persistence/api/entity/EntityFactory.java | 4 -
.../task/MacroTask.java} | 24 +-
.../persistence/api/entity/task/TaskUtils.java | 10 +
.../entity/anyobject/JPAJSONAnyObjectListener.java | 7 +-
.../jpa/entity/group/JPAJSONGroupListener.java | 7 +-
.../entity/user/JPAJSONLinkedAccountListener.java | 7 +-
.../jpa/entity/user/JPAJSONUserListener.java | 7 +-
.../resources/domains/jpa-json/MasterContent.xml | 3 +
.../src/test/resources/domains/MasterContent.xml | 4 +
.../core/persistence/jpa/PersistenceContext.java | 26 +-
.../jpa/dao/DefaultPullCorrelationRule.java | 5 +-
.../persistence/jpa/dao/JPAImplementationDAO.java | 20 +-
.../core/persistence/jpa/dao/JPARealmDAO.java | 23 +-
.../core/persistence/jpa/dao/JPATaskDAO.java | 237 +++++++-------
.../core/persistence/jpa/dao/JPATaskExecDAO.java | 86 +-----
.../persistence/jpa/entity/JPAConnInstance.java | 8 +-
.../persistence/jpa/entity/JPAEntityFactory.java | 48 +--
.../jpa/entity/JPAExternalResource.java | 16 +-
.../persistence/jpa/entity/JPANotification.java | 11 +-
.../core/persistence/jpa/entity/JPARole.java | 6 +-
.../jpa/entity/am/AbstractClientApp.java | 6 +-
.../persistence/jpa/entity/am/JPAAttrRepo.java | 9 +-
.../persistence/jpa/entity/am/JPAAuthModule.java | 9 +-
.../persistence/jpa/entity/am/JPAAuthProfile.java | 36 ++-
.../jpa/entity/am/JPAOIDCRPClientApp.java | 23 +-
.../jpa/entity/am/JPASAML2SPClientApp.java | 37 +--
.../jpa/entity/am/JPAWAConfigEntry.java | 8 +-
.../persistence/jpa/entity/task/JPAMacroTask.java | 178 +++++++++++
.../jpa/entity/task/JPAMacroTaskExec.java | 49 +++
.../jpa/entity/task/JPANotificationTask.java | 7 +-
.../persistence/jpa/entity/task/JPASchedTask.java | 20 +-
.../persistence/jpa/entity/task/JPATaskUtils.java | 216 ++++++++++++-
.../jpa/entity/task/JPATaskUtilsFactory.java | 15 +-
.../core/persistence/jpa/entity/user/JPAUser.java | 54 ++--
.../src/main/resources/domains/MasterContent.xml | 3 +
.../persistence/jpa/inner/ImplementationTest.java | 4 +-
.../core/persistence/jpa/inner/TaskExecTest.java | 6 +-
.../core/persistence/jpa/inner/TaskTest.java | 22 ++
.../core/persistence/jpa/outer/TaskTest.java | 10 +-
.../src/test/resources/domains/MasterContent.xml | 4 +
.../provisioning/api/serialization/POJOHelper.java | 12 +
.../core/provisioning/api/utils/RealmUtils.java | 21 +-
.../provisioning/java/ProvisioningContext.java | 8 +-
.../java/data/ImplementationDataBinderImpl.java | 101 ++----
.../java/data/ResourceDataBinderImpl.java | 4 +-
.../provisioning/java/data/TaskDataBinderImpl.java | 145 ++++++---
.../java/job/AbstractSchedTaskJobDelegate.java | 6 +-
.../provisioning/java/job/DefaultJobManager.java | 11 +-
.../core/provisioning/java/job/TaskJob.java | 5 +-
.../DefaultNotificationJobDelegate.java | 10 +-
.../AbstractPropagationTaskExecutor.java | 11 +-
.../PriorityPropagationTaskExecutor.java | 3 -
.../pushpull/AbstractProvisioningJobDelegate.java | 66 ++--
.../pushpull/DefaultRealmPullResultHandler.java | 38 ++-
.../implementation/ImplementationManager.java | 24 ++
.../security/DelegatedAdministrationException.java | 2 +-
.../fit/core/reference/ITImplementationLookup.java | 7 +
.../fit/core/reference/TestAccountRuleConf.java | 5 -
.../syncope/fit/core/reference/TestCommand.java | 69 +++++
.../fit/core/reference/TestCommandArgs.java | 65 ++++
.../fit/core/reference/TestPasswordRuleConf.java | 5 -
.../org/apache/syncope/fit/AbstractITCase.java | 4 +
.../syncope/fit/console/AjaxBrowseITCase.java | 4 +
.../syncope/fit/console/EngagementsITCase.java | 57 ++++
.../apache/syncope/fit/console/PoliciesITCase.java | 8 +-
.../apache/syncope/fit/console/ReportsITCase.java | 4 +-
.../apache/syncope/fit/console/TopologyITCase.java | 37 +--
.../org/apache/syncope/fit/core/CommandITCase.java | 99 ++++++
.../apache/syncope/fit/core/DelegationITCase.java | 12 +-
.../org/apache/syncope/fit/core/MacroITCase.java | 160 ++++++++++
.../org/apache/syncope/fit/core/RealmITCase.java | 4 +-
.../org/apache/syncope/fit/core/RoleITCase.java | 2 +-
.../test/resources/DoubleValueLogicActions.groovy | 3 +-
.../src/test/resources/GroovyCommand.groovy | 22 +-
.../src/test/resources/TestPullRule.groovy | 1 -
.../src/test/resources/TestPushRule.groovy | 1 -
pom.xml | 6 +-
src/main/asciidoc/images/consoleDashboard.png | Bin 62451 -> 63518 bytes
src/main/asciidoc/images/engagements.png | Bin 0 -> 40213 bytes
.../reference-guide/concepts/notifications.adoc | 2 +-
.../asciidoc/reference-guide/concepts/realms.adoc | 4 +-
.../asciidoc/reference-guide/concepts/tasks.adoc | 41 ++-
.../configuration/highavailability.adoc | 4 +-
.../reference-guide/usage/adminconsole.adoc | 8 +
.../reference-guide/usage/customization.adoc | 8 +-
234 files changed, 4535 insertions(+), 1965 deletions(-)
diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/authprofiles/AuthProfileDirectoryPanel.java b/client/am/console/src/main/java/org/apache/syncope/client/console/authprofiles/AuthProfileDirectoryPanel.java
index 474957f0e3..1066f1268c 100644
--- a/client/am/console/src/main/java/org/apache/syncope/client/console/authprofiles/AuthProfileDirectoryPanel.java
+++ b/client/am/console/src/main/java/org/apache/syncope/client/console/authprofiles/AuthProfileDirectoryPanel.java
@@ -64,7 +64,7 @@ import org.apache.wicket.model.StringResourceModel;
public class AuthProfileDirectoryPanel
extends DirectoryPanel<AuthProfileTO, AuthProfileTO, AuthProfileProvider, AuthProfileRestClient> {
- private static final long serialVersionUID = 1L;
+ private static final long serialVersionUID = 2018518567549153364L;
private final BaseModal<AuthProfileTO> authProfileModal;
@@ -121,6 +121,8 @@ public class AuthProfileDirectoryPanel
columns.add(new BooleanConditionColumn<>(new StringResourceModel("impersonationAccounts")) {
+ private static final long serialVersionUID = -8236820422411536323L;
+
@Override
protected boolean isCondition(final IModel<AuthProfileTO> rowModel) {
return !rowModel.getObject().getImpersonationAccounts().isEmpty();
@@ -128,6 +130,8 @@ public class AuthProfileDirectoryPanel
});
columns.add(new BooleanConditionColumn<>(new StringResourceModel("googleMfaAuthTokens")) {
+ private static final long serialVersionUID = -8236820422411536323L;
+
@Override
protected boolean isCondition(final IModel<AuthProfileTO> rowModel) {
return !rowModel.getObject().getGoogleMfaAuthTokens().isEmpty();
@@ -135,6 +139,8 @@ public class AuthProfileDirectoryPanel
});
columns.add(new BooleanConditionColumn<>(new StringResourceModel("googleMfaAuthAccounts")) {
+ private static final long serialVersionUID = -8236820422411536323L;
+
@Override
protected boolean isCondition(final IModel<AuthProfileTO> rowModel) {
return !rowModel.getObject().getGoogleMfaAuthAccounts().isEmpty();
@@ -142,6 +148,8 @@ public class AuthProfileDirectoryPanel
});
columns.add(new BooleanConditionColumn<>(new StringResourceModel("u2fRegisteredDevices")) {
+ private static final long serialVersionUID = -8236820422411536323L;
+
@Override
protected boolean isCondition(final IModel<AuthProfileTO> rowModel) {
return !rowModel.getObject().getU2FRegisteredDevices().isEmpty();
@@ -149,6 +157,8 @@ public class AuthProfileDirectoryPanel
});
columns.add(new BooleanConditionColumn<>(new StringResourceModel("webAuthnAccount")) {
+ private static final long serialVersionUID = -8236820422411536323L;
+
@Override
protected boolean isCondition(final IModel<AuthProfileTO> rowModel) {
return !rowModel.getObject().getWebAuthnDeviceCredentials().isEmpty();
@@ -170,38 +180,40 @@ public class AuthProfileDirectoryPanel
public void onClick(final AjaxRequestTarget target, final AuthProfileTO ignore) {
model.setObject(AuthProfileRestClient.read(model.getObject().getKey()));
target.add(authProfileModal.setContent(new ModalDirectoryPanel<>(
- authProfileModal,
- new AuthProfileItemDirectoryPanel<ImpersonationAccount>(
- "panel", authProfileModal, model.getObject(), pageRef) {
-
- @Override
- protected List<ImpersonationAccount> getItems() {
- return model.getObject().getImpersonationAccounts();
- }
-
- @Override
- protected ImpersonationAccount defaultItem() {
- return new ImpersonationAccount();
- }
-
- @Override
- protected String sortProperty() {
- return "impersonated";
- }
-
- @Override
- protected String paginatorRowsKey() {
- return AMConstants.PREF_AUTHPROFILE_IMPERSONATED_PAGINATOR_ROWS;
- }
-
- @Override
- protected List<IColumn<ImpersonationAccount, String>> getColumns() {
- List<IColumn<ImpersonationAccount, String>> columns = new ArrayList<>();
- columns.add(new PropertyColumn<>(new ResourceModel("impersonated"),
+ authProfileModal,
+ new AuthProfileItemDirectoryPanel<ImpersonationAccount>(
+ "panel", authProfileModal, model.getObject(), pageRef) {
+
+ private static final long serialVersionUID = -5380664539000792237L;
+
+ @Override
+ protected List<ImpersonationAccount> getItems() {
+ return model.getObject().getImpersonationAccounts();
+ }
+
+ @Override
+ protected ImpersonationAccount defaultItem() {
+ return new ImpersonationAccount();
+ }
+
+ @Override
+ protected String sortProperty() {
+ return "impersonated";
+ }
+
+ @Override
+ protected String paginatorRowsKey() {
+ return AMConstants.PREF_AUTHPROFILE_IMPERSONATED_PAGINATOR_ROWS;
+ }
+
+ @Override
+ protected List<IColumn<ImpersonationAccount, String>> getColumns() {
+ List<IColumn<ImpersonationAccount, String>> columns = new ArrayList<>();
+ columns.add(new PropertyColumn<>(new ResourceModel("impersonated"),
"impersonated", "impersonated"));
- return columns;
- }
- }, pageRef)));
+ return columns;
+ }
+ }, pageRef)));
authProfileModal.header(new Model<>(getString("impersonationAccounts", model)));
authProfileModal.show(true);
}
@@ -215,40 +227,42 @@ public class AuthProfileDirectoryPanel
public void onClick(final AjaxRequestTarget target, final AuthProfileTO ignore) {
model.setObject(AuthProfileRestClient.read(model.getObject().getKey()));
target.add(authProfileModal.setContent(new ModalDirectoryPanel<>(
- authProfileModal,
- new AuthProfileItemDirectoryPanel<GoogleMfaAuthToken>(
- "panel", authProfileModal, model.getObject(), pageRef) {
-
- @Override
- protected List<GoogleMfaAuthToken> getItems() {
- return model.getObject().getGoogleMfaAuthTokens();
- }
-
- @Override
- protected GoogleMfaAuthToken defaultItem() {
- return new GoogleMfaAuthToken();
- }
-
- @Override
- protected String sortProperty() {
- return "issueDate";
- }
-
- @Override
- protected String paginatorRowsKey() {
- return AMConstants.PREF_AUTHPROFILE_GOOGLEMFAAUTHTOKENS_PAGINATOR_ROWS;
- }
-
- @Override
- protected List<IColumn<GoogleMfaAuthToken, String>> getColumns() {
- List<IColumn<GoogleMfaAuthToken, String>> columns = new ArrayList<>();
- columns.add(new DatePropertyColumn<>(
+ authProfileModal,
+ new AuthProfileItemDirectoryPanel<GoogleMfaAuthToken>(
+ "panel", authProfileModal, model.getObject(), pageRef) {
+
+ private static final long serialVersionUID = 7332357430197837993L;
+
+ @Override
+ protected List<GoogleMfaAuthToken> getItems() {
+ return model.getObject().getGoogleMfaAuthTokens();
+ }
+
+ @Override
+ protected GoogleMfaAuthToken defaultItem() {
+ return new GoogleMfaAuthToken();
+ }
+
+ @Override
+ protected String sortProperty() {
+ return "issueDate";
+ }
+
+ @Override
+ protected String paginatorRowsKey() {
+ return AMConstants.PREF_AUTHPROFILE_GOOGLEMFAAUTHTOKENS_PAGINATOR_ROWS;
+ }
+
+ @Override
+ protected List<IColumn<GoogleMfaAuthToken, String>> getColumns() {
+ List<IColumn<GoogleMfaAuthToken, String>> columns = new ArrayList<>();
+ columns.add(new DatePropertyColumn<>(
new ResourceModel("issueDate"), "issueDate", "issueDate"));
- columns.add(new PropertyColumn<>(
+ columns.add(new PropertyColumn<>(
new ResourceModel("otp"), "otp", "otp"));
- return columns;
- }
- }, pageRef)));
+ return columns;
+ }
+ }, pageRef)));
authProfileModal.header(new Model<>(getString("googleMfaAuthTokens", model)));
authProfileModal.show(true);
}
@@ -262,40 +276,42 @@ public class AuthProfileDirectoryPanel
public void onClick(final AjaxRequestTarget target, final AuthProfileTO ignore) {
model.setObject(AuthProfileRestClient.read(model.getObject().getKey()));
target.add(authProfileModal.setContent(new ModalDirectoryPanel<>(
- authProfileModal,
- new AuthProfileItemDirectoryPanel<GoogleMfaAuthAccount>(
- "panel", authProfileModal, model.getObject(), pageRef) {
-
- @Override
- protected List<GoogleMfaAuthAccount> getItems() {
- return model.getObject().getGoogleMfaAuthAccounts();
- }
-
- @Override
- protected GoogleMfaAuthAccount defaultItem() {
- return new GoogleMfaAuthAccount();
- }
-
- @Override
- protected String sortProperty() {
- return "id";
- }
-
- @Override
- protected String paginatorRowsKey() {
- return AMConstants.PREF_AUTHPROFILE_GOOGLEMFAAUTHACCOUNTS_PAGINATOR_ROWS;
- }
-
- @Override
- protected List<IColumn<GoogleMfaAuthAccount, String>> getColumns() {
- List<IColumn<GoogleMfaAuthAccount, String>> columns = new ArrayList<>();
- columns.add(new PropertyColumn<>(new ResourceModel("id"), "id", "id"));
- columns.add(new DatePropertyColumn<>(
+ authProfileModal,
+ new AuthProfileItemDirectoryPanel<GoogleMfaAuthAccount>(
+ "panel", authProfileModal, model.getObject(), pageRef) {
+
+ private static final long serialVersionUID = -670769282358547044L;
+
+ @Override
+ protected List<GoogleMfaAuthAccount> getItems() {
+ return model.getObject().getGoogleMfaAuthAccounts();
+ }
+
+ @Override
+ protected GoogleMfaAuthAccount defaultItem() {
+ return new GoogleMfaAuthAccount();
+ }
+
+ @Override
+ protected String sortProperty() {
+ return "id";
+ }
+
+ @Override
+ protected String paginatorRowsKey() {
+ return AMConstants.PREF_AUTHPROFILE_GOOGLEMFAAUTHACCOUNTS_PAGINATOR_ROWS;
+ }
+
+ @Override
+ protected List<IColumn<GoogleMfaAuthAccount, String>> getColumns() {
+ List<IColumn<GoogleMfaAuthAccount, String>> columns = new ArrayList<>();
+ columns.add(new PropertyColumn<>(new ResourceModel("id"), "id", "id"));
+ columns.add(new DatePropertyColumn<>(
new ResourceModel("registrationDate"), "registrationDate", "registrationDate"));
- columns.add(new PropertyColumn<>(new ResourceModel("name"), "name", "name"));
- return columns;
- }
- }, pageRef)));
+ columns.add(new PropertyColumn<>(new ResourceModel("name"), "name", "name"));
+ return columns;
+ }
+ }, pageRef)));
authProfileModal.header(new Model<>(getString("googleMfaAuthAccounts", model)));
authProfileModal.show(true);
}
@@ -309,40 +325,42 @@ public class AuthProfileDirectoryPanel
public void onClick(final AjaxRequestTarget target, final AuthProfileTO ignore) {
model.setObject(AuthProfileRestClient.read(model.getObject().getKey()));
target.add(authProfileModal.setContent(new ModalDirectoryPanel<>(
- authProfileModal,
- new AuthProfileItemDirectoryPanel<U2FDevice>(
- "panel", authProfileModal, model.getObject(), pageRef) {
-
- @Override
- protected List<U2FDevice> getItems() {
- return model.getObject().getU2FRegisteredDevices();
- }
-
- @Override
- protected U2FDevice defaultItem() {
- return new U2FDevice();
- }
-
- @Override
- protected String sortProperty() {
- return "id";
- }
-
- @Override
- protected String paginatorRowsKey() {
- return AMConstants.PREF_AUTHPROFILE_U2FDEVICES_PAGINATOR_ROWS;
- }
-
- @Override
- protected List<IColumn<U2FDevice, String>> getColumns() {
- List<IColumn<U2FDevice, String>> columns = new ArrayList<>();
- columns.add(new PropertyColumn<>(new ResourceModel("id"), "id", "id"));
- columns.add(new DatePropertyColumn<>(
+ authProfileModal,
+ new AuthProfileItemDirectoryPanel<U2FDevice>(
+ "panel", authProfileModal, model.getObject(), pageRef) {
+
+ private static final long serialVersionUID = 5788448799796630011L;
+
+ @Override
+ protected List<U2FDevice> getItems() {
+ return model.getObject().getU2FRegisteredDevices();
+ }
+
+ @Override
+ protected U2FDevice defaultItem() {
+ return new U2FDevice();
+ }
+
+ @Override
+ protected String sortProperty() {
+ return "id";
+ }
+
+ @Override
+ protected String paginatorRowsKey() {
+ return AMConstants.PREF_AUTHPROFILE_U2FDEVICES_PAGINATOR_ROWS;
+ }
+
+ @Override
+ protected List<IColumn<U2FDevice, String>> getColumns() {
+ List<IColumn<U2FDevice, String>> columns = new ArrayList<>();
+ columns.add(new PropertyColumn<>(new ResourceModel("id"), "id", "id"));
+ columns.add(new DatePropertyColumn<>(
new ResourceModel("issueDate"), "issueDate", "issueDate"));
- columns.add(new PropertyColumn<>(new ResourceModel("record"), "record", "record"));
- return columns;
- }
- }, pageRef)));
+ columns.add(new PropertyColumn<>(new ResourceModel("record"), "record", "record"));
+ return columns;
+ }
+ }, pageRef)));
authProfileModal.header(new Model<>(getString("u2fRegisteredDevices", model)));
authProfileModal.show(true);
}
@@ -356,40 +374,42 @@ public class AuthProfileDirectoryPanel
public void onClick(final AjaxRequestTarget target, final AuthProfileTO ignore) {
model.setObject(AuthProfileRestClient.read(model.getObject().getKey()));
target.add(authProfileModal.setContent(new ModalDirectoryPanel<>(
- authProfileModal,
- new AuthProfileItemDirectoryPanel<WebAuthnDeviceCredential>(
- "panel", authProfileModal, model.getObject(), pageRef) {
-
- @Override
- protected List<WebAuthnDeviceCredential> getItems() {
- return model.getObject().getWebAuthnDeviceCredentials();
- }
-
- @Override
- protected WebAuthnDeviceCredential defaultItem() {
- return new WebAuthnDeviceCredential();
- }
-
- @Override
- protected String sortProperty() {
- return "identifier";
- }
-
- @Override
- protected String paginatorRowsKey() {
- return AMConstants.PREF_AUTHPROFILE_WEBAUTHNDEVICECREDENTIALS_PAGINATOR_ROWS;
- }
-
- @Override
- protected List<IColumn<WebAuthnDeviceCredential, String>> getColumns() {
- List<IColumn<WebAuthnDeviceCredential, String>> columns = new ArrayList<>();
- columns.add(new PropertyColumn<>(
+ authProfileModal,
+ new AuthProfileItemDirectoryPanel<WebAuthnDeviceCredential>(
+ "panel", authProfileModal, model.getObject(), pageRef) {
+
+ private static final long serialVersionUID = 6820212423488933184L;
+
+ @Override
+ protected List<WebAuthnDeviceCredential> getItems() {
+ return model.getObject().getWebAuthnDeviceCredentials();
+ }
+
+ @Override
+ protected WebAuthnDeviceCredential defaultItem() {
+ return new WebAuthnDeviceCredential();
+ }
+
+ @Override
+ protected String sortProperty() {
+ return "identifier";
+ }
+
+ @Override
+ protected String paginatorRowsKey() {
+ return AMConstants.PREF_AUTHPROFILE_WEBAUTHNDEVICECREDENTIALS_PAGINATOR_ROWS;
+ }
+
+ @Override
+ protected List<IColumn<WebAuthnDeviceCredential, String>> getColumns() {
+ List<IColumn<WebAuthnDeviceCredential, String>> columns = new ArrayList<>();
+ columns.add(new PropertyColumn<>(
new ResourceModel("identifier"), "identifier", "identifier"));
- columns.add(new PropertyColumn<>(
+ columns.add(new PropertyColumn<>(
new ResourceModel("json"), "json", "json"));
- return columns;
- }
- }, pageRef)));
+ return columns;
+ }
+ }, pageRef)));
authProfileModal.header(new Model<>(getString("webAuthnDeviceCredentials", model)));
authProfileModal.show(true);
}
diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/authprofiles/AuthProfileItemDirectoryPanel.java b/client/am/console/src/main/java/org/apache/syncope/client/console/authprofiles/AuthProfileItemDirectoryPanel.java
index 5543a00097..a125278ef7 100644
--- a/client/am/console/src/main/java/org/apache/syncope/client/console/authprofiles/AuthProfileItemDirectoryPanel.java
+++ b/client/am/console/src/main/java/org/apache/syncope/client/console/authprofiles/AuthProfileItemDirectoryPanel.java
@@ -120,7 +120,7 @@ public abstract class AuthProfileItemDirectoryPanel<I extends BaseBean>
@Override
public void onClick(final AjaxRequestTarget target, final I ignore) {
send(AuthProfileItemDirectoryPanel.this, Broadcast.EXACT,
- new AjaxWizard.EditItemActionEvent<>(model.getObject(), target));
+ new AjaxWizard.EditItemActionEvent<>(model.getObject(), target));
}
}, ActionLink.ActionType.EDIT, AMEntitlement.AUTH_PROFILE_UPDATE);
@@ -178,11 +178,11 @@ public abstract class AuthProfileItemDirectoryPanel<I extends BaseBean>
}
}
- private class AuthProfileItemWizardBuilder extends AuthProfileWizardBuilder<I> {
+ protected class AuthProfileItemWizardBuilder extends AuthProfileWizardBuilder<I> {
- private static final long serialVersionUID = 1L;
+ private static final long serialVersionUID = -7174537333960225216L;
- AuthProfileItemWizardBuilder(final PageReference pageRef) {
+ protected AuthProfileItemWizardBuilder(final PageReference pageRef) {
super(defaultItem(), new StepModel<>(), pageRef);
}
diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel.java b/client/am/console/src/main/java/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel.java
index 9cdc7e7a30..68ea786219 100644
--- a/client/am/console/src/main/java/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel.java
+++ b/client/am/console/src/main/java/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel.java
@@ -57,7 +57,7 @@ import org.apache.wicket.model.StringResourceModel;
public abstract class ClientAppDirectoryPanel<T extends ClientAppTO>
extends DirectoryPanel<T, T, DirectoryDataProvider<T>, ClientAppRestClient> {
- private static final long serialVersionUID = 1L;
+ private static final long serialVersionUID = 4100100988730985059L;
private final ClientAppType type;
@@ -123,8 +123,8 @@ public abstract class ClientAppDirectoryPanel<T extends ClientAppTO>
@Override
public void onClick(final AjaxRequestTarget target, final ClientAppTO ignore) {
send(ClientAppDirectoryPanel.this, Broadcast.EXACT,
- new AjaxWizard.EditItemActionEvent<>(
- ClientAppRestClient.read(type, model.getObject().getKey()), target));
+ new AjaxWizard.EditItemActionEvent<>(
+ ClientAppRestClient.read(type, model.getObject().getKey()), target));
}
}, ActionLink.ActionType.EDIT, AMEntitlement.CLIENTAPP_UPDATE);
@@ -136,9 +136,9 @@ public abstract class ClientAppDirectoryPanel<T extends ClientAppTO>
public void onClick(final AjaxRequestTarget target, final ClientAppTO ignore) {
model.setObject(ClientAppRestClient.read(type, model.getObject().getKey()));
target.add(propertiesModal.setContent(new ModalDirectoryPanel<>(
- propertiesModal,
- new ClientAppPropertiesDirectoryPanel<>("panel", propertiesModal, type, model, pageRef),
- pageRef)));
+ propertiesModal,
+ new ClientAppPropertiesDirectoryPanel<>("panel", propertiesModal, type, model, pageRef),
+ pageRef)));
propertiesModal.header(new Model<>(getString("properties.title", model)));
propertiesModal.show(true);
}
@@ -154,7 +154,7 @@ public abstract class ClientAppDirectoryPanel<T extends ClientAppTO>
clone.setKey(null);
clone.setClientAppId(null);
send(ClientAppDirectoryPanel.this, Broadcast.EXACT,
- new AjaxWizard.EditItemActionEvent<>(clone, target));
+ new AjaxWizard.EditItemActionEvent<>(clone, target));
}
}, ActionLink.ActionType.CLONE, AMEntitlement.CLIENTAPP_CREATE);
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMAnyDirectoryPanelAdditionalActionLinksProvider.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMAnyDirectoryPanelAdditionalActionLinksProvider.java
index 9ae35163f9..6a17806fe3 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMAnyDirectoryPanelAdditionalActionLinksProvider.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMAnyDirectoryPanelAdditionalActionLinksProvider.java
@@ -68,15 +68,14 @@ public class IdMAnyDirectoryPanelAdditionalActionLinksProvider
@Override
public void onClick(final AjaxRequestTarget target, final UserTO ignore) {
IModel<AnyWrapper<UserTO>> formModel = new CompoundPropertyModel<>(
- new AnyWrapper<>(model.getObject()));
+ new AnyWrapper<>(model.getObject()));
modal.setFormModel(formModel);
target.add(modal.setContent(new AnyStatusModal<>(
- modal,
- pageRef,
- formModel.getObject().getInnerObject(),
- "resource",
- true)));
+ pageRef,
+ formModel.getObject().getInnerObject(),
+ "resource",
+ true)));
modal.header(new Model<>(header));
@@ -96,15 +95,14 @@ public class IdMAnyDirectoryPanelAdditionalActionLinksProvider
public void onClick(final AjaxRequestTarget target, final UserTO ignore) {
model.setObject(new UserRestClient().read(model.getObject().getKey()));
IModel<AnyWrapper<UserTO>> formModel = new CompoundPropertyModel<>(
- new AnyWrapper<>(model.getObject()));
+ new AnyWrapper<>(model.getObject()));
modal.setFormModel(formModel);
target.add(modal.setContent(new AnyStatusModal<>(
- modal,
- pageRef,
- formModel.getObject().getInnerObject(),
- "resource",
- false)));
+ pageRef,
+ formModel.getObject().getInnerObject(),
+ "resource",
+ false)));
modal.header(new Model<>(header));
@@ -146,7 +144,7 @@ public class IdMAnyDirectoryPanelAdditionalActionLinksProvider
public void onClick(final AjaxRequestTarget target, final UserTO ignore) {
model.setObject(new UserRestClient().read(model.getObject().getKey()));
MergeLinkedAccountsWizardBuilder builder =
- new MergeLinkedAccountsWizardBuilder(model, pageRef, parentPanel, modal);
+ new MergeLinkedAccountsWizardBuilder(model, pageRef, parentPanel, modal);
builder.setEventSink(builder);
target.add(modal.setContent(builder.build(BaseModal.CONTENT_ID, AjaxWizard.Mode.CREATE)));
modal.header(new StringResourceModel("mergeLinkedAccounts.title", model));
@@ -179,15 +177,14 @@ public class IdMAnyDirectoryPanelAdditionalActionLinksProvider
@Override
public void onClick(final AjaxRequestTarget target, final GroupTO ignore) {
IModel<AnyWrapper<GroupTO>> formModel = new CompoundPropertyModel<>(
- new AnyWrapper<>(modelObject));
+ new AnyWrapper<>(modelObject));
modal.setFormModel(formModel);
target.add(modal.setContent(new AnyStatusModal<>(
- modal,
- pageRef,
- formModel.getObject().getInnerObject(),
- "resource",
- false)));
+ pageRef,
+ formModel.getObject().getInnerObject(),
+ "resource",
+ false)));
modal.header(new Model<>(header));
@@ -222,15 +219,14 @@ public class IdMAnyDirectoryPanelAdditionalActionLinksProvider
@Override
public void onClick(final AjaxRequestTarget target, final AnyObjectTO ignore) {
final IModel<AnyWrapper<AnyObjectTO>> formModel = new CompoundPropertyModel<>(
- new AnyWrapper<>(modelObject));
+ new AnyWrapper<>(modelObject));
modal.setFormModel(formModel);
target.add(modal.setContent(new AnyStatusModal<>(
- modal,
- pageRef,
- formModel.getObject().getInnerObject(),
- "resource",
- false)));
+ pageRef,
+ formModel.getObject().getInnerObject(),
+ "resource",
+ false)));
modal.header(new Model<>(header));
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDirectoryPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDirectoryPanel.java
index 81cd889938..6432ce3122 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDirectoryPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDirectoryPanel.java
@@ -257,10 +257,10 @@ public class ResourceDirectoryPanel extends
@Override
public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
- target.add(schedTaskModal.setContent(new PullTasks(schedTaskModal, pageRef,
- ((ResourceTO) model.getObject()).getKey())));
- schedTaskModal.header(new Model<>(MessageFormat.format(getString("task.pull.list"),
- ((ResourceTO) model.getObject()).getKey())));
+ target.add(schedTaskModal.setContent(new PullTasks(
+ schedTaskModal, ((ResourceTO) model.getObject()).getKey(), pageRef)));
+ schedTaskModal.header(new Model<>(
+ MessageFormat.format(getString("task.pull.list"), ((ResourceTO) model.getObject()).getKey())));
schedTaskModal.show(true);
}
}, ActionLink.ActionType.PULL_TASKS, IdRepoEntitlement.TASK_LIST);
@@ -271,10 +271,10 @@ public class ResourceDirectoryPanel extends
@Override
public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
- target.add(schedTaskModal.setContent(new PushTasks(schedTaskModal, pageRef,
- ((ResourceTO) model.getObject()).getKey())));
- schedTaskModal.header(new Model<>(MessageFormat.format(getString("task.push.list"),
- ((ResourceTO) model.getObject()).getKey())));
+ target.add(schedTaskModal.setContent(new PushTasks(
+ schedTaskModal, ((ResourceTO) model.getObject()).getKey(), pageRef)));
+ schedTaskModal.header(new Model<>(
+ MessageFormat.format(getString("task.push.list"), ((ResourceTO) model.getObject()).getKey())));
schedTaskModal.show(true);
}
}, ActionLink.ActionType.PUSH_TASKS, IdRepoEntitlement.TASK_LIST);
@@ -286,8 +286,7 @@ public class ResourceDirectoryPanel extends
@Override
public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
ResourceTO modelObject = ResourceRestClient.read(((ResourceTO) model.getObject()).getKey());
- target.add(propTaskModal.setContent(
- new ResourceStatusModal(propTaskModal, pageRef, modelObject)));
+ target.add(propTaskModal.setContent(new ResourceStatusModal(pageRef, modelObject)));
propTaskModal.header(new Model<>(MessageFormat.format(getString("resource.reconciliation"),
((ResourceTO) model.getObject()).getKey())));
propTaskModal.show(true);
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java
index 7c45f5c99b..0b8007c45b 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java
@@ -34,7 +34,6 @@ import org.apache.syncope.client.console.rest.AnyObjectRestClient;
import org.apache.syncope.client.console.rest.GroupRestClient;
import org.apache.syncope.client.console.rest.ResourceRestClient;
import org.apache.syncope.client.console.rest.UserRestClient;
-import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
import org.apache.syncope.client.ui.commons.Constants;
@@ -73,8 +72,6 @@ public class AnyStatusDirectoryPanel
private static final long serialVersionUID = -9148734710505211261L;
- private final BaseModal<?> baseModal;
-
private final MultilevelPanel multiLevelPanelRef;
private final AnyTO anyTO;
@@ -86,7 +83,6 @@ public class AnyStatusDirectoryPanel
private final List<String> resources;
public AnyStatusDirectoryPanel(
- final BaseModal<?> baseModal,
final MultilevelPanel multiLevelPanelRef,
final PageReference pageRef,
final AnyTO anyTO,
@@ -94,7 +90,6 @@ public class AnyStatusDirectoryPanel
final boolean statusOnly) {
super(MultilevelPanel.FIRST_LEVEL_ID, pageRef);
- this.baseModal = baseModal;
this.multiLevelPanelRef = multiLevelPanelRef;
this.statusOnly = statusOnly;
this.anyTO = anyTO;
@@ -120,23 +115,23 @@ public class AnyStatusDirectoryPanel
@Override
protected void resultTableCustomChanges(final AjaxDataTablePanel.Builder<StatusBean, String> resultTableBuilder) {
- resultTableBuilder.setMultiLevelPanel(baseModal, multiLevelPanelRef);
+ resultTableBuilder.setMultiLevelPanel(multiLevelPanelRef);
}
@Override
protected List<IColumn<StatusBean, String>> getColumns() {
- final List<IColumn<StatusBean, String>> columns = new ArrayList<>();
+ List<IColumn<StatusBean, String>> columns = new ArrayList<>();
columns.add(new AbstractColumn<>(
- new StringResourceModel("resource", this), "resource") {
+ new StringResourceModel("resource", this), "resource") {
private static final long serialVersionUID = 2054811145491901166L;
@Override
public void populateItem(
- final Item<ICellPopulator<StatusBean>> cellItem,
- final String componentId,
- final IModel<StatusBean> model) {
+ final Item<ICellPopulator<StatusBean>> cellItem,
+ final String componentId,
+ final IModel<StatusBean> model) {
cellItem.add(new Label(componentId, model.getObject().getResource()) {
@@ -145,7 +140,7 @@ public class AnyStatusDirectoryPanel
@Override
protected void onComponentTag(final ComponentTag tag) {
if (anyTO.getResources().contains(model.getObject().getResource())
- || Constants.SYNCOPE.equalsIgnoreCase(model.getObject().getResource())) {
+ || Constants.SYNCOPE.equalsIgnoreCase(model.getObject().getResource())) {
super.onComponentTag(tag);
} else {
@@ -166,9 +161,9 @@ public class AnyStatusDirectoryPanel
@Override
public void populateItem(
- final Item<ICellPopulator<StatusBean>> cellItem,
- final String componentId,
- final IModel<StatusBean> model) {
+ final Item<ICellPopulator<StatusBean>> cellItem,
+ final String componentId,
+ final IModel<StatusBean> model) {
if (model.getObject().isLinked()) {
cellItem.add(StatusUtils.getStatusImage(componentId, model.getObject().getStatus()));
@@ -194,8 +189,8 @@ public class AnyStatusDirectoryPanel
@Override
public void onClick(final AjaxRequestTarget target, final StatusBean bean) {
multiLevelPanelRef.next(bean.getResource(),
- new ReconStatusPanel(bean.getResource(), anyTO.getType(), anyTO.getKey()),
- target);
+ new ReconStatusPanel(bean.getResource(), anyTO.getType(), anyTO.getKey()),
+ target);
target.add(multiLevelPanelRef);
AnyStatusDirectoryPanel.this.getTogglePanel().close(target);
}
@@ -210,15 +205,15 @@ public class AnyStatusDirectoryPanel
@Override
public void onClick(final AjaxRequestTarget target, final StatusBean bean) {
multiLevelPanelRef.next("PUSH " + bean.getResource(),
- new ReconTaskPanel(
- bean.getResource(),
- new PushTaskTO(),
- anyTO.getType(),
- anyTO.getKey(),
- true,
- multiLevelPanelRef,
- pageRef),
- target);
+ new ReconTaskPanel(
+ bean.getResource(),
+ new PushTaskTO(),
+ anyTO.getType(),
+ anyTO.getKey(),
+ true,
+ multiLevelPanelRef,
+ pageRef),
+ target);
target.add(multiLevelPanelRef);
AnyStatusDirectoryPanel.this.getTogglePanel().close(target);
}
@@ -231,15 +226,15 @@ public class AnyStatusDirectoryPanel
@Override
public void onClick(final AjaxRequestTarget target, final StatusBean bean) {
multiLevelPanelRef.next("PULL " + bean.getResource(),
- new ReconTaskPanel(
- bean.getResource(),
- new PullTaskTO(),
- anyTO.getType(),
- anyTO.getKey(),
- true,
- multiLevelPanelRef,
- pageRef),
- target);
+ new ReconTaskPanel(
+ bean.getResource(),
+ new PullTaskTO(),
+ anyTO.getType(),
+ anyTO.getKey(),
+ true,
+ multiLevelPanelRef,
+ pageRef),
+ target);
target.add(multiLevelPanelRef);
AnyStatusDirectoryPanel.this.getTogglePanel().close(target);
}
@@ -256,17 +251,17 @@ public class AnyStatusDirectoryPanel
panel.add(new ActionLink<>() {
- private static final long serialVersionUID = 5168094747477174155L;
-
- @Override
- public void onClick(final AjaxRequestTarget target, final StatusBean bean) {
- multiLevelPanelRef.next("ACCOUNTS",
- new LinkedAccountsStatusModalPanel(Model.of(UserTO.class.cast(anyTO)), pageRef),
- target);
- target.add(multiLevelPanelRef);
- AnyStatusDirectoryPanel.this.getTogglePanel().close(target);
- }
- }, ActionLink.ActionType.MANAGE_ACCOUNTS,
+ private static final long serialVersionUID = 5168094747477174155L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final StatusBean bean) {
+ multiLevelPanelRef.next("ACCOUNTS",
+ new LinkedAccountsStatusModalPanel(Model.of(UserTO.class.cast(anyTO)), pageRef),
+ target);
+ target.add(multiLevelPanelRef);
+ AnyStatusDirectoryPanel.this.getTogglePanel().close(target);
+ }
+ }, ActionLink.ActionType.MANAGE_ACCOUNTS,
String.format("%s,%s,%s", IdRepoEntitlement.USER_READ, IdRepoEntitlement.USER_UPDATE,
IdMEntitlement.RESOURCE_GET_CONNOBJECT));
}
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusModal.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusModal.java
index 6bb17a63b1..166996da5b 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusModal.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusModal.java
@@ -21,7 +21,6 @@ package org.apache.syncope.client.console.status;
import org.apache.syncope.client.console.panels.DirectoryPanel;
import org.apache.syncope.client.console.panels.MultilevelPanel;
import org.apache.syncope.client.console.rest.AbstractAnyRestClient;
-import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
import org.apache.syncope.client.ui.commons.DirectoryDataProvider;
import org.apache.syncope.client.ui.commons.status.StatusBean;
import org.apache.syncope.common.lib.to.AnyTO;
@@ -32,25 +31,23 @@ public class AnyStatusModal<T extends AnyTO> extends StatusModal<T> {
private static final long serialVersionUID = 1066124171682570080L;
public AnyStatusModal(
- final BaseModal<?> baseModal,
final PageReference pageReference,
final T anyTO,
final String itemKeyFieldName,
final boolean statusOnly) {
- super(baseModal, pageReference, anyTO, itemKeyFieldName, statusOnly);
+ super(pageReference, anyTO, itemKeyFieldName, statusOnly);
}
@Override
protected DirectoryPanel<
StatusBean, StatusBean, DirectoryDataProvider<StatusBean>, AbstractAnyRestClient<?>> getStatusDirectoryPanel(
final MultilevelPanel mlp,
- final BaseModal<?> baseModal,
final PageReference pageReference,
final T entity,
final String itemKeyFieldName,
final boolean statusOnly) {
- return new AnyStatusDirectoryPanel(baseModal, mlp, pageReference, entity, itemKeyFieldName, statusOnly);
+ return new AnyStatusDirectoryPanel(mlp, pageReference, entity, itemKeyFieldName, statusOnly);
}
}
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusDirectoryPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusDirectoryPanel.java
index 3bb36d2b48..bff2bbba54 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusDirectoryPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusDirectoryPanel.java
@@ -33,7 +33,6 @@ import org.apache.syncope.client.console.rest.AbstractAnyRestClient;
import org.apache.syncope.client.console.rest.AnyObjectRestClient;
import org.apache.syncope.client.console.rest.GroupRestClient;
import org.apache.syncope.client.console.rest.UserRestClient;
-import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
import org.apache.syncope.client.lib.SyncopeClient;
@@ -65,8 +64,6 @@ public class ResourceStatusDirectoryPanel
private static final long serialVersionUID = -9148734710505211261L;
- private final BaseModal<?> baseModal;
-
private final MultilevelPanel multiLevelPanelRef;
private String type;
@@ -74,14 +71,12 @@ public class ResourceStatusDirectoryPanel
private final ResourceTO resource;
public ResourceStatusDirectoryPanel(
- final BaseModal<?> baseModal,
final MultilevelPanel multiLevelPanelRef,
final PageReference pageRef,
final String type,
final ResourceTO resource) {
super(MultilevelPanel.FIRST_LEVEL_ID, pageRef);
- this.baseModal = baseModal;
this.multiLevelPanelRef = multiLevelPanelRef;
this.type = type;
this.resource = resource;
@@ -92,7 +87,7 @@ public class ResourceStatusDirectoryPanel
@Override
protected void resultTableCustomChanges(final AjaxDataTablePanel.Builder<StatusBean, String> resultTableBuilder) {
- resultTableBuilder.setMultiLevelPanel(baseModal, multiLevelPanelRef);
+ resultTableBuilder.setMultiLevelPanel(multiLevelPanelRef);
}
@Override
@@ -121,8 +116,8 @@ public class ResourceStatusDirectoryPanel
@Override
public void onClick(final AjaxRequestTarget target, final StatusBean bean) {
multiLevelPanelRef.next(bean.getResource(),
- new ReconStatusPanel(bean.getResource(), type, bean.getKey()),
- target);
+ new ReconStatusPanel(bean.getResource(), type, bean.getKey()),
+ target);
target.add(multiLevelPanelRef);
getTogglePanel().close(target);
}
@@ -140,15 +135,15 @@ public class ResourceStatusDirectoryPanel
@Override
public void onClick(final AjaxRequestTarget target, final StatusBean bean) {
multiLevelPanelRef.next("PUSH " + bean.getResource(),
- new ReconTaskPanel(
- bean.getResource(),
- new PushTaskTO(),
- type,
- bean.getKey(),
- true,
- multiLevelPanelRef,
- pageRef),
- target);
+ new ReconTaskPanel(
+ bean.getResource(),
+ new PushTaskTO(),
+ type,
+ bean.getKey(),
+ true,
+ multiLevelPanelRef,
+ pageRef),
+ target);
target.add(multiLevelPanelRef);
getTogglePanel().close(target);
}
@@ -166,15 +161,15 @@ public class ResourceStatusDirectoryPanel
@Override
public void onClick(final AjaxRequestTarget target, final StatusBean bean) {
multiLevelPanelRef.next("PULL " + bean.getResource(),
- new ReconTaskPanel(
- bean.getResource(),
- new PullTaskTO(),
- type,
- bean.getKey(),
- true,
- multiLevelPanelRef,
- pageRef),
- target);
+ new ReconTaskPanel(
+ bean.getResource(),
+ new PullTaskTO(),
+ type,
+ bean.getKey(),
+ true,
+ multiLevelPanelRef,
+ pageRef),
+ target);
target.add(multiLevelPanelRef);
getTogglePanel().close(target);
}
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusModal.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusModal.java
index 0399dc1f30..3ab581b962 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusModal.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusModal.java
@@ -24,7 +24,6 @@ import org.apache.syncope.client.console.panels.DirectoryPanel;
import org.apache.syncope.client.console.panels.MultilevelPanel;
import org.apache.syncope.client.console.rest.AbstractAnyRestClient;
import org.apache.syncope.client.console.rest.AnyTypeRestClient;
-import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
import org.apache.syncope.client.ui.commons.Constants;
import org.apache.syncope.client.ui.commons.DirectoryDataProvider;
import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDropDownChoicePanel;
@@ -43,11 +42,10 @@ public class ResourceStatusModal extends StatusModal<ResourceTO> {
private Model<String> typeModel = new Model<>();
public ResourceStatusModal(
- final BaseModal<?> baseModal,
- final PageReference pageReference,
+ final PageReference pageRef,
final ResourceTO resource) {
- super(baseModal, pageReference, resource, null, false);
+ super(pageRef, resource, null, false);
List<String> availableAnyTypes = resource.getProvisions().stream().
map(Provision::getAnyType).
@@ -76,12 +74,11 @@ public class ResourceStatusModal extends StatusModal<ResourceTO> {
protected DirectoryPanel<
StatusBean, StatusBean, DirectoryDataProvider<StatusBean>, AbstractAnyRestClient<?>> getStatusDirectoryPanel(
final MultilevelPanel mlp,
- final BaseModal<?> baseModal,
final PageReference pageReference,
final ResourceTO entity,
final String itemKeyFieldName,
final boolean statusOnly) {
- return new ResourceStatusDirectoryPanel(baseModal, mlp, pageReference, null, entity);
+ return new ResourceStatusDirectoryPanel(mlp, pageReference, null, entity);
}
}
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/status/StatusModal.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/status/StatusModal.java
index 7aaf0794d3..a723ffaea3 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/status/StatusModal.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/status/StatusModal.java
@@ -36,7 +36,6 @@ public abstract class StatusModal<T extends EntityTO> extends Panel implements M
protected final DirectoryPanel<StatusBean, StatusBean, ?, ?> directoryPanel;
public StatusModal(
- final BaseModal<?> baseModal,
final PageReference pageReference,
final T entity,
final String itemKeyFieldName,
@@ -44,17 +43,15 @@ public abstract class StatusModal<T extends EntityTO> extends Panel implements M
super(BaseModal.CONTENT_ID);
- final MultilevelPanel mlp = new MultilevelPanel("status");
+ MultilevelPanel mlp = new MultilevelPanel("status");
mlp.setOutputMarkupId(true);
- this.directoryPanel = getStatusDirectoryPanel(
- mlp, baseModal, pageReference, entity, itemKeyFieldName, statusOnly);
- add(mlp.setFirstLevel(this.directoryPanel));
+ directoryPanel = getStatusDirectoryPanel(mlp, pageReference, entity, itemKeyFieldName, statusOnly);
+ add(mlp.setFirstLevel(directoryPanel));
}
protected abstract DirectoryPanel<
StatusBean, StatusBean, DirectoryDataProvider<StatusBean>, AbstractAnyRestClient<?>> getStatusDirectoryPanel(
MultilevelPanel mlp,
- BaseModal<?> baseModal,
PageReference pageReference,
T entity,
String itemKeyFieldName,
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TabularTopology.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TabularTopology.java
index 946e5d445f..02ae460c80 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TabularTopology.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TabularTopology.java
@@ -18,9 +18,7 @@
*/
package org.apache.syncope.client.console.topology;
-import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
import de.agilecoders.wicket.core.markup.html.bootstrap.tabs.AjaxBootstrapTabbedPanel;
-import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.apache.syncope.client.console.annotations.IdMPage;
@@ -28,9 +26,6 @@ import org.apache.syncope.client.console.pages.BasePage;
import org.apache.syncope.client.console.pages.Connectors;
import org.apache.syncope.client.console.pages.Resources;
import org.apache.syncope.client.console.panels.ConnidLocations;
-import org.apache.syncope.client.console.tasks.SchedTasks;
-import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
-import org.apache.syncope.client.ui.commons.Constants;
import org.apache.syncope.common.lib.types.IdMEntitlement;
import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
import org.apache.wicket.extensions.markup.html.tabs.ITab;
@@ -54,28 +49,7 @@ public class TabularTopology extends BasePage {
}
protected List<ITab> buildTabList() {
- final List<ITab> tabs = new ArrayList<>();
-
- tabs.add(new AbstractTab(new Model<>("CustomTasks")) {
-
- private static final long serialVersionUID = -6815067322125799251L;
-
- @Override
- public Panel getPanel(final String panelId) {
- BaseModal<Serializable> schedTaskModal = new BaseModal<>(Constants.OUTER) {
-
- private static final long serialVersionUID = -1673561782333149836L;
-
- @Override
- protected void onConfigure() {
- super.onConfigure();
- setFooterVisible(false);
- }
- };
- schedTaskModal.size(Modal.Size.Large);
- return new SchedTasks(schedTaskModal, getPageReference(), true, panelId);
- }
- });
+ List<ITab> tabs = new ArrayList<>();
tabs.add(new AbstractTab(new Model<>("Resources")) {
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
index a45072f82c..aeb8ec3e64 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
@@ -33,7 +33,6 @@ import org.apache.syncope.client.console.status.ResourceStatusModal;
import org.apache.syncope.client.console.tasks.PropagationTasks;
import org.apache.syncope.client.console.tasks.PullTasks;
import org.apache.syncope.client.console.tasks.PushTasks;
-import org.apache.syncope.client.console.tasks.SchedTasks;
import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
import org.apache.syncope.client.console.wicket.markup.html.form.IndicatingOnConfirmAjaxLink;
import org.apache.syncope.client.console.wizards.resources.ConnectorWizardBuilder;
@@ -62,7 +61,6 @@ import org.apache.wicket.markup.html.panel.Fragment;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
-import org.apache.wicket.model.ResourceModel;
import org.apache.wicket.model.StringResourceModel;
public class TopologyTogglePanel extends TogglePanel<Serializable> {
@@ -190,25 +188,6 @@ public class TopologyTogglePanel extends TogglePanel<Serializable> {
fragment.add(reload);
MetaDataRoleAuthorizationStrategy.authorize(reload, RENDER, IdMEntitlement.CONNECTOR_RELOAD);
- AjaxLink<String> tasks = new IndicatingAjaxLink<>("tasks") {
-
- private static final long serialVersionUID = 3776750333491622263L;
-
- @Override
- public void onClick(final AjaxRequestTarget target) {
- target.add(schedTaskModal.setContent(new SchedTasks(schedTaskModal, pageRef)));
- schedTaskModal.header(new ResourceModel("task.custom.list"));
- schedTaskModal.show(true);
- }
-
- @Override
- public String getAjaxIndicatorMarkupId() {
- return Constants.VEIL_INDICATOR_MARKUP_ID;
- }
- };
- fragment.add(tasks);
- MetaDataRoleAuthorizationStrategy.authorize(tasks, RENDER, IdRepoEntitlement.TASK_LIST);
-
return fragment;
}
@@ -313,8 +292,8 @@ public class TopologyTogglePanel extends TogglePanel<Serializable> {
build(BaseModal.CONTENT_ID,
SyncopeConsoleSession.get().
owns(IdMEntitlement.CONNECTOR_UPDATE, connInstance.getAdminRealm())
- ? AjaxWizard.Mode.EDIT
- : AjaxWizard.Mode.READONLY)));
+ ? AjaxWizard.Mode.EDIT
+ : AjaxWizard.Mode.READONLY)));
modal.header(
new Model<>(MessageFormat.format(getString("connector.edit"), connInstance.getDisplayName())));
@@ -419,8 +398,8 @@ public class TopologyTogglePanel extends TogglePanel<Serializable> {
build(BaseModal.CONTENT_ID,
SyncopeConsoleSession.get().
owns(IdMEntitlement.RESOURCE_UPDATE, connInstance.getAdminRealm())
- ? AjaxWizard.Mode.EDIT
- : AjaxWizard.Mode.READONLY)));
+ ? AjaxWizard.Mode.EDIT
+ : AjaxWizard.Mode.READONLY)));
modal.header(new Model<>(MessageFormat.format(getString("resource.edit"), node.getKey())));
modal.show(true);
@@ -441,8 +420,7 @@ public class TopologyTogglePanel extends TogglePanel<Serializable> {
@Override
public void onClick(final AjaxRequestTarget target) {
ResourceTO modelObject = ResourceRestClient.read(node.getKey());
- target.add(propTaskModal.setContent(
- new ResourceStatusModal(propTaskModal, pageRef, modelObject)));
+ target.add(propTaskModal.setContent(new ResourceStatusModal(pageRef, modelObject)));
propTaskModal.header(
new Model<>(MessageFormat.format(getString("resource.reconciliation"), node.getKey())));
propTaskModal.show(true);
@@ -540,7 +518,7 @@ public class TopologyTogglePanel extends TogglePanel<Serializable> {
@Override
public void onClick(final AjaxRequestTarget target) {
- target.add(schedTaskModal.setContent(new PullTasks(schedTaskModal, pageRef, node.getKey())));
+ target.add(schedTaskModal.setContent(new PullTasks(schedTaskModal, node.getKey(), pageRef)));
schedTaskModal.header(new Model<>(MessageFormat.format(getString("task.pull.list"), node.getKey())));
schedTaskModal.show(true);
}
@@ -559,7 +537,7 @@ public class TopologyTogglePanel extends TogglePanel<Serializable> {
@Override
public void onClick(final AjaxRequestTarget target) {
- target.add(schedTaskModal.setContent(new PushTasks(schedTaskModal, pageRef, node.getKey())));
+ target.add(schedTaskModal.setContent(new PushTasks(schedTaskModal, node.getKey(), pageRef)));
schedTaskModal.header(new Model<>(MessageFormat.format(getString("task.push.list"), node.getKey())));
schedTaskModal.show(true);
}
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel.html b/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel.html
index 8794ecb5d9..64be1d7e3b 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel.html
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel.html
@@ -94,9 +94,6 @@ under the License.
<wicket:enclosure child="reload">
<li><a href="#" wicket:id="reload"><i class="fa fa-sync"></i><wicket:message key="connectors.reload"/></a></li>
</wicket:enclosure>
- <wicket:enclosure child="tasks">
- <li><a href="#" wicket:id="tasks"><i class="fa fa-tasks"></i><wicket:message key="task.custom.list"/></a></li>
- </wicket:enclosure>
</ul>
</wicket:fragment>
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel.properties
index 22cce2d2ec..6ade698bec 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel.properties
@@ -31,8 +31,6 @@ resource.menu.provision=Edit provision rules
resource.menu.explore=Explore resource
resource.menu.history=Configuration history
resource.menu.clone=Clone resource
-
-task.custom.list=Custom tasks
task.propagation.list=Propagation tasks {0}
task.pull.list=Pull tasks {0}
task.push.list=Push tasks {0}
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_fr_CA.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_fr_CA.properties
index 838f3b30f6..fde8651859 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_fr_CA.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_fr_CA.properties
@@ -26,18 +26,17 @@ resource.clone=Cloner la ressource {0}
resource.menu.add=Ajouter une nouvelle ressource
resource.menu.remove=Supprimer une ressource
resource.menu.edit=Modifier la ressource
-resource.menu.provision=Modifier les r�gles de provision
+resource.menu.provision=Modifier les r\u00e8gles de provision
resource.menu.explore=Explorer la ressource
resource.menu.history=Historique de configuration
resource.menu.clone=Cloner la ressource
-task.custom.list=T�ches personnalis�es
-task.propagation.list=T�ches de propagation {0}
-task.pull.list=T�ches de traction {0}
-task.push.list=T�ches de pouss�e {0}
+task.propagation.list=T\u00e2ches de propagation {0}
+task.pull.list=T\u00e2ches de traction {0}
+task.push.list=T\u00e2ches de pouss\u00e9e {0}
resource.explore.list=Explorer ${key}
connectors.reload=Recharger tous les connecteurs
-resource.reconciliation=R�conciliation {0}
+resource.reconciliation=R\u00e9conciliation {0}
resource.menu.reconciliation=Rapprochement
-resource.menu.push.list=T�ches de pouss�e
-resource.menu.pull.list=T�ches d'extraction
-resource.menu.propagation.list=T�ches de propagation
+resource.menu.push.list=T\u00e2ches de pouss\u00e9e
+resource.menu.pull.list=T\u00e2ches d'extraction
+resource.menu.propagation.list=T\u00e2ches de propagation
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_it.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_it.properties
index ec33424648..618ad09663 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_it.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_it.properties
@@ -31,8 +31,6 @@ resource.menu.provision=Modifica regole di provisioning
resource.menu.explore=Esplora risorsa
resource.menu.history=Storico delle configurazioni
resource.menu.clone=Duplica risorsa
-
-task.custom.list=Task personalizzati
task.propagation.list=Task di propagazione {0}
task.pull.list=Pull task {0}
task.push.list=Push task {0}
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_ja.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_ja.properties
index 0b70bf0e62..befad7fc37 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_ja.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_ja.properties
@@ -31,8 +31,6 @@ resource.menu.provision=\u30d7\u30ed\u30d3\u30b8\u30e7\u30f3\u30eb\u30fc\u30eb\u
resource.menu.explore=\u30ea\u30bd\u30fc\u30b9\u3092\u63a2\u7d22
resource.menu.history=\u8a2d\u5b9a\u5c65\u6b74
resource.menu.clone=\u30ea\u30bd\u30fc\u30b9\u3092\u8907\u88fd
-
-task.custom.list=\u30ab\u30b9\u30bf\u30e0\u30bf\u30b9\u30af
task.propagation.list=\u4f1d\u64ad\u30bf\u30b9\u30af {0}
task.pull.list=\u30d7\u30eb\u30bf\u30b9\u30af {0}
task.push.list=\u30d7\u30c3\u30b7\u30e5\u30bf\u30b9\u30af {0}
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_pt_BR.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_pt_BR.properties
index ee13fed7d8..7bf53cd4e6 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_pt_BR.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_pt_BR.properties
@@ -31,8 +31,6 @@ resource.menu.provision=Alterar regras de provision
resource.menu.explore=Explorar recurso
resource.menu.history=Hist\u00f3rico de configura\u00e7\u00e3o
resource.menu.clone=Clone recurso
-
-task.custom.list=Custom tasks
task.propagation.list=Propagation tasks {0}
task.pull.list=Pull tasks {0}
task.push.list=Push tasks {0}
diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_ru.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_ru.properties
index fc2b246ec0..b017f0ecf3 100644
--- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_ru.properties
+++ b/client/idm/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_ru.properties
@@ -32,8 +32,6 @@ resource.menu.provision=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043f\
resource.menu.explore=\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 \u0440\u0435\u0441\u0443\u0440\u0441\u0430
resource.menu.history=\u0418\u0441\u0442\u043e\u0440\u0438\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438
resource.menu.clone=\u0414\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0441\u0443\u0440\u0441
-
-task.custom.list=\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438
task.propagation.list=\u0417\u0430\u0434\u0430\u0447\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 {0}
task.pull.list=\u0417\u0430\u0434\u0430\u0447\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 {0}
task.push.list=\u0417\u0430\u0434\u0430\u0447\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 {0}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/audit/AuditHistoryDetails.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/audit/AuditHistoryDetails.java
index 713727c8f2..cf538151ac 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/audit/AuditHistoryDetails.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/audit/AuditHistoryDetails.java
@@ -74,6 +74,7 @@ public abstract class AuditHistoryDetails<T extends Serializable> extends Panel
private static final SortParam<String> REST_SORT = new SortParam<>("event_date", false);
private EntityTO currentEntity;
+
private AuditElements.EventCategoryType type;
private String category;
@@ -90,7 +91,7 @@ public abstract class AuditHistoryDetails<T extends Serializable> extends Panel
private AjaxDropDownChoicePanel<AuditEntry> afterVersionsPanel;
- private AjaxLink<Void> restore;
+ private final AjaxLink<Void> restore;
private static class SortingNodeFactory extends JsonNodeFactory {
@@ -156,6 +157,7 @@ public abstract class AuditHistoryDetails<T extends Serializable> extends Panel
registerModule(new SimpleModule().addSerializer(new SortedSetJsonSerializer(cast(Set.class)))).
registerModule(new JavaTimeModule());
+ @SuppressWarnings("unchecked")
public AuditHistoryDetails(
final String id,
final EntityTO currentEntity,
@@ -187,10 +189,10 @@ public abstract class AuditHistoryDetails<T extends Serializable> extends Panel
@Override
public AuditEntry getObject(final String id, final IModel<? extends List<? extends AuditEntry>> choices) {
- return choices.getObject().stream()
- .filter(c -> StringUtils.isNotBlank(id)
- && Long.valueOf(id) == c.getDate().toInstant().toEpochMilli()).findFirst()
- .orElse(null);
+ return choices.getObject().stream().
+ filter(c -> StringUtils.isNotBlank(id)
+ && Long.parseLong(id) == c.getDate().toInstant().toEpochMilli()).
+ findFirst().orElse(null);
}
};
// add also select to choose with which version compare
@@ -213,10 +215,10 @@ public abstract class AuditHistoryDetails<T extends Serializable> extends Panel
AuditHistoryDetails.this.addOrReplace(new JsonDiffPanel(toJSON(beforeEntry, reference),
toJSON(afterEntry, reference)));
// change after audit entries in order to match only the ones newer than the current after one
- afterVersionsPanel.setChoices(auditEntries.stream().filter(ae ->
- ae.getDate().isAfter(beforeEntry.getDate())
- || ae.getDate().isEqual(beforeEntry.getDate()))
- .collect(Collectors.toList()));
+ afterVersionsPanel.setChoices(auditEntries.stream().
+ filter(ae -> ae.getDate().isAfter(beforeEntry.getDate())
+ || ae.getDate().isEqual(beforeEntry.getDate())).
+ collect(Collectors.toList()));
// set the new after entry
afterVersionsPanel.setModelObject(afterEntry);
target.add(AuditHistoryDetails.this);
@@ -232,13 +234,13 @@ public abstract class AuditHistoryDetails<T extends Serializable> extends Panel
@Override
protected void onEvent(final AjaxRequestTarget target) {
- AuditHistoryDetails.this.addOrReplace(
- new JsonDiffPanel(toJSON(beforeVersionsPanel.getModelObject() == null
+ AuditHistoryDetails.this.addOrReplace(new JsonDiffPanel(
+ toJSON(beforeVersionsPanel.getModelObject() == null
? latestAuditEntry
: beforeVersionsPanel.getModelObject(), reference),
- toJSON(afterVersionsPanel.getModelObject() == null
- ? after
- : buildAfterAuditEntry(afterVersionsPanel.getModelObject()), reference)));
+ toJSON(afterVersionsPanel.getModelObject() == null
+ ? after
+ : buildAfterAuditEntry(afterVersionsPanel.getModelObject()), reference)));
target.add(AuditHistoryDetails.this);
}
});
@@ -268,7 +270,7 @@ public abstract class AuditHistoryDetails<T extends Serializable> extends Panel
};
MetaDataRoleAuthorizationStrategy.authorize(restore, ENABLE, auditRestoreEntitlement);
add(restore);
-
+
initDiff();
}
@@ -294,9 +296,9 @@ public abstract class AuditHistoryDetails<T extends Serializable> extends Panel
addOrReplace(new JsonDiffPanel(toJSON(latestAuditEntry, reference), toJSON(after, reference)));
beforeVersionsPanel.setChoices(auditEntries);
- afterVersionsPanel.setChoices(auditEntries.stream().filter(ae ->
- ae.getDate().isAfter(after.getDate()) || ae.getDate().isEqual(after.getDate())).collect(
- Collectors.toList()));
+ afterVersionsPanel.setChoices(auditEntries.stream().
+ filter(ae -> ae.getDate().isAfter(after.getDate()) || ae.getDate().isEqual(after.getDate())).
+ collect(Collectors.toList()));
beforeVersionsPanel.setModelObject(latestAuditEntry);
afterVersionsPanel.setModelObject(after);
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/audit/AuditHistoryModal.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/audit/AuditHistoryModal.java
index ccbf968ddf..5f6c181315 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/audit/AuditHistoryModal.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/audit/AuditHistoryModal.java
@@ -37,7 +37,7 @@ public abstract class AuditHistoryModal<T extends EntityTO> extends Panel implem
super(BaseModal.CONTENT_ID);
- add(new AuditHistoryDetails(
+ add(new AuditHistoryDetails<>(
"history",
entity,
type,
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/IdRepoConstants.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/IdRepoConstants.java
index ff5b475e59..6af40b7ff1 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/IdRepoConstants.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/IdRepoConstants.java
@@ -66,6 +66,8 @@ public final class IdRepoConstants {
public static final String PREF_ACCESS_TOKEN_PAGINATOR_ROWS = "accessToken.paginator.rows";
+ public static final String PREF_COMMAND_PAGINATOR_ROWS = "command.paginator.rows";
+
public static final String PREF_AUDIT_HISTORY_PAGINATOR_ROWS = "audit.history.paginator.rows";
public static final String PREF_NOTIFICATION_PAGINATOR_ROWS = "notification.paginator.rows";
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/IdRepoImplementationInfoProvider.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/IdRepoImplementationInfoProvider.java
index dd12dffa52..121c9fd2c2 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/IdRepoImplementationInfoProvider.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/IdRepoImplementationInfoProvider.java
@@ -123,6 +123,10 @@ public class IdRepoImplementationInfoProvider implements ImplementationInfoProvi
templateClassName = "MyItemTransformer";
break;
+ case IdRepoImplementationType.COMMAND:
+ templateClassName = "MyCommand";
+ break;
+
default:
}
@@ -163,7 +167,7 @@ public class IdRepoImplementationInfoProvider implements ImplementationInfoProvi
@Override
protected List<String> load() {
return ImplementationRestClient.list(IdRepoImplementationType.TASKJOB_DELEGATE).stream().
- map(ImplementationTO::getKey).sorted().collect(Collectors.toList());
+ map(ImplementationTO::getKey).sorted().collect(Collectors.toList());
}
};
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ModalDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/KeywordSearchEvent.java
similarity index 58%
copy from client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ModalDirectoryPanel.java
copy to client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/KeywordSearchEvent.java
index 6d524c537c..e35627bd83 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ModalDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/KeywordSearchEvent.java
@@ -16,20 +16,29 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.syncope.client.console.panels;
+package org.apache.syncope.client.console.commons;
import java.io.Serializable;
-import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
-import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
-public class ModalDirectoryPanel<T extends Serializable> extends AbstractModalPanel<T> {
+public class KeywordSearchEvent implements Serializable {
- private static final long serialVersionUID = 1L;
+ private static final long serialVersionUID = 203866008113326777L;
- public ModalDirectoryPanel(
- final BaseModal<T> modal, final DirectoryPanel<?, ?, ?, ?> directoryPanel, final PageReference pageRef) {
+ private final AjaxRequestTarget target;
- super(modal, pageRef);
- add(directoryPanel);
+ private final String keyword;
+
+ public KeywordSearchEvent(final AjaxRequestTarget target, final String keyword) {
+ this.target = target;
+ this.keyword = keyword;
+ }
+
+ public AjaxRequestTarget getTarget() {
+ return target;
+ }
+
+ public String getKeyword() {
+ return keyword;
}
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/LinkedAccountPlainAttrProperty.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/LinkedAccountPlainAttrProperty.java
index 3f0468a929..6ce77c97fc 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/LinkedAccountPlainAttrProperty.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/LinkedAccountPlainAttrProperty.java
@@ -18,20 +18,15 @@
*/
package org.apache.syncope.client.console.commons;
-import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
-@XmlRootElement
-@XmlType
public class LinkedAccountPlainAttrProperty implements Serializable, Comparable<LinkedAccountPlainAttrProperty> {
private static final long serialVersionUID = -5309050337675968950L;
@@ -50,9 +45,8 @@ public class LinkedAccountPlainAttrProperty implements Serializable, Comparable<
this.schema = schema;
}
- @XmlElementWrapper(name = "values")
- @XmlElement(name = "value")
- @JsonProperty("values")
+ @JacksonXmlElementWrapper(localName = "values")
+ @JacksonXmlProperty(localName = "value")
public List<String> getValues() {
return values;
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/notifications/NotificationTasks.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/notifications/NotificationTasks.java
index 82e9369420..0af41223fa 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/notifications/NotificationTasks.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/notifications/NotificationTasks.java
@@ -68,10 +68,10 @@ public class NotificationTasks extends Panel implements ModalPanel {
private static final long serialVersionUID = -2195387360323687302L;
@Override
- protected void viewTask(final NotificationTaskTO taskTO, final AjaxRequestTarget target) {
+ protected void viewTaskExecs(final NotificationTaskTO taskTO, final AjaxRequestTarget target) {
mlp.next(
new StringResourceModel("task.view", this, new Model<>(Pair.of(null, taskTO))).getObject(),
- new TaskExecutionDetails<>(null, taskTO, pageReference), target);
+ new TaskExecutionDetails<>(taskTO, pageReference), target);
}
@Override
@@ -82,7 +82,6 @@ public class NotificationTasks extends Panel implements ModalPanel {
new StringResourceModel("content", this).setParameters(format.name()).getObject(),
new NotificationMailBodyDetails(content), target);
}
-
});
}
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
index e29dbe7bef..b60d9c7aa5 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
@@ -122,12 +122,12 @@ public class BasePage extends BaseWebPage {
public void onClick() {
try {
HttpResourceStream stream = new HttpResourceStream(
- new ResponseHolder(SyncopeRestClient.exportInternalStorageContent()));
+ new ResponseHolder(SyncopeRestClient.exportInternalStorageContent()));
ResourceStreamRequestHandler rsrh = new ResourceStreamRequestHandler(stream);
rsrh.setFileName(stream.getFilename() == null
- ? SyncopeConsoleSession.get().getDomain() + "Content.xml"
- : stream.getFilename());
+ ? SyncopeConsoleSession.get().getDomain() + "Content.xml"
+ : stream.getFilename());
rsrh.setContentDisposition(ContentDisposition.ATTACHMENT);
rsrh.setCacheDuration(Duration.ZERO);
@@ -153,6 +153,13 @@ public class BasePage extends BaseWebPage {
liContainer.add(link);
+ liContainer = new WebMarkupContainer(getLIContainerId("engagements"));
+ body.add(liContainer);
+ link = BookmarkablePageLinkBuilder.build("engagements", Engagements.class);
+ MetaDataRoleAuthorizationStrategy.authorize(link, WebPage.RENDER,
+ String.format("%s,%s", IdRepoEntitlement.TASK_LIST, IdRepoEntitlement.IMPLEMENTATION_LIST));
+ liContainer.add(link);
+
liContainer = new WebMarkupContainer(getLIContainerId("reports"));
body.add(liContainer);
link = BookmarkablePageLinkBuilder.build("reports", Reports.class);
@@ -160,8 +167,7 @@ public class BasePage extends BaseWebPage {
liContainer.add(link);
List<Class<? extends BasePage>> idmPageClasses = SyncopeWebApplication.get().getLookup().getIdMPageClasses();
- ListView<Class<? extends BasePage>> idmPages = new ListView<>(
- "idmPages", idmPageClasses) {
+ ListView<Class<? extends BasePage>> idmPages = new ListView<>("idmPages", idmPageClasses) {
private static final long serialVersionUID = 4949588177564901031L;
@@ -200,8 +206,7 @@ public class BasePage extends BaseWebPage {
body.add(idmPages);
List<Class<? extends BasePage>> amPageClasses = SyncopeWebApplication.get().getLookup().getAMPageClasses();
- ListView<Class<? extends BasePage>> amPages = new ListView<>(
- "amPages", amPageClasses) {
+ ListView<Class<? extends BasePage>> amPages = new ListView<>("amPages", amPageClasses) {
private static final long serialVersionUID = -9112553137618363167L;
@@ -337,6 +342,8 @@ public class BasePage extends BaseWebPage {
delegationsContainer.add(new Label("delegationsHeader", new ResourceModel("delegations")));
delegationsContainer.add(new ListView<>("delegations", SyncopeConsoleSession.get().getDelegations()) {
+ private static final long serialVersionUID = -9112553137618363167L;
+
@Override
protected void populateItem(final ListItem<String> item) {
item.add(new DelegationSelectionPanel("delegation", item.getModelObject()));
@@ -345,6 +352,8 @@ public class BasePage extends BaseWebPage {
body.add(new IndicatingOnConfirmAjaxLink<String>("endDelegation", "confirmDelegation", true) {
+ private static final long serialVersionUID = 1632838687547839512L;
+
@Override
public void onClick(final AjaxRequestTarget target) {
SyncopeConsoleSession.get().setDelegatedBy(null);
@@ -467,7 +476,7 @@ public class BasePage extends BaseWebPage {
List<Class<? extends ExtAlertWidget<?>>> extAlertWidgetClasses =
SyncopeWebApplication.get().getLookup().getExtAlertWidgetClasses();
ListView<Class<? extends ExtAlertWidget<?>>> extAlertWidgets = new ListView<>(
- "extAlertWidgets", extAlertWidgetClasses) {
+ "extAlertWidgets", extAlertWidgetClasses) {
private static final long serialVersionUID = -9112553137618363167L;
@@ -475,7 +484,7 @@ public class BasePage extends BaseWebPage {
protected void populateItem(final ListItem<Class<? extends ExtAlertWidget<?>>> item) {
try {
Constructor<? extends ExtAlertWidget<?>> constructor =
- item.getModelObject().getDeclaredConstructor(String.class, PageReference.class);
+ item.getModelObject().getDeclaredConstructor(String.class, PageReference.class);
ExtAlertWidget<?> widget = constructor.newInstance("extAlertWidget", getPageReference());
SyncopeConsoleSession.get().setAttribute(widget.getClass().getName(), widget);
@@ -497,46 +506,46 @@ public class BasePage extends BaseWebPage {
body.add(extensionsLI);
ListView<Class<? extends BaseExtPage>> extPages =
- new ListView<>("extPages", extPageClasses) {
+ new ListView<>("extPages", extPageClasses) {
- private static final long serialVersionUID = 4949588177564901031L;
+ private static final long serialVersionUID = 4949588177564901031L;
- @Override
- protected void populateItem(final ListItem<Class<? extends BaseExtPage>> item) {
- WebMarkupContainer containingLI = new WebMarkupContainer("extPageLI");
- item.add(containingLI);
+ @Override
+ protected void populateItem(final ListItem<Class<? extends BaseExtPage>> item) {
+ WebMarkupContainer containingLI = new WebMarkupContainer("extPageLI");
+ item.add(containingLI);
- ExtPage ann = item.getModelObject().getAnnotation(ExtPage.class);
+ ExtPage ann = item.getModelObject().getAnnotation(ExtPage.class);
- BookmarkablePageLink<Page> link = new BookmarkablePageLink<>("extPage", item.getModelObject());
- link.add(new Label("extPageLabel", ann.label()));
- if (StringUtils.isNotBlank(ann.listEntitlement())) {
- MetaDataRoleAuthorizationStrategy.authorize(link, WebPage.RENDER, ann.listEntitlement());
- }
- if (item.getModelObject().equals(BasePage.this.getClass())) {
- link.add(new Behavior() {
+ BookmarkablePageLink<Page> link = new BookmarkablePageLink<>("extPage", item.getModelObject());
+ link.add(new Label("extPageLabel", ann.label()));
+ if (StringUtils.isNotBlank(ann.listEntitlement())) {
+ MetaDataRoleAuthorizationStrategy.authorize(link, WebPage.RENDER, ann.listEntitlement());
+ }
+ if (item.getModelObject().equals(BasePage.this.getClass())) {
+ link.add(new Behavior() {
- private static final long serialVersionUID = 1469628524240283489L;
+ private static final long serialVersionUID = 1469628524240283489L;
- @Override
- public void renderHead(final Component component, final IHeaderResponse response) {
- response.render(OnDomReadyHeaderItem.forScript(
+ @Override
+ public void renderHead(final Component component, final IHeaderResponse response) {
+ response.render(OnDomReadyHeaderItem.forScript(
"$('#extensionsLink').addClass('active')"));
- }
-
- @Override
- public void onComponentTag(final Component component, final ComponentTag tag) {
- tag.append("class", "active", " ");
- }
- });
- }
- containingLI.add(link);
+ }
- Label extPageIcon = new Label("extPageIcon");
- extPageIcon.add(new AttributeModifier("class", "nav-icon " + ann.icon()));
- link.add(extPageIcon);
+ @Override
+ public void onComponentTag(final Component component, final ComponentTag tag) {
+ tag.append("class", "active", " ");
+ }
+ });
}
- };
+ containingLI.add(link);
+
+ Label extPageIcon = new Label("extPageIcon");
+ extPageIcon.add(new AttributeModifier("class", "nav-icon " + ann.icon()));
+ link.add(extPageIcon);
+ }
+ };
extPages.setRenderBodyOnly(true);
extPages.setOutputMarkupId(true);
extensionsLI.add(extPages);
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Reports.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Engagements.java
similarity index 60%
copy from client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Reports.java
copy to client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Engagements.java
index 46763162a2..249e5fc139 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Reports.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Engagements.java
@@ -21,12 +21,15 @@ package org.apache.syncope.client.console.pages;
import de.agilecoders.wicket.core.markup.html.bootstrap.tabs.AjaxBootstrapTabbedPanel;
import java.util.ArrayList;
import java.util.List;
+import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
+import org.apache.syncope.client.console.panels.CommandsPanel;
import org.apache.syncope.client.console.panels.MultilevelPanel;
-import org.apache.syncope.client.console.reports.ReportDirectoryPanel;
-import org.apache.syncope.client.console.reports.ReportExecutionDetails;
-import org.apache.syncope.client.console.reports.ReportTemplateDirectoryPanel;
-import org.apache.syncope.common.lib.to.ReportTO;
+import org.apache.syncope.client.console.tasks.MacroTaskDirectoryPanel;
+import org.apache.syncope.client.console.tasks.SchedTaskDirectoryPanel;
+import org.apache.syncope.client.console.tasks.TaskExecutionDetails;
+import org.apache.syncope.common.lib.to.SchedTaskTO;
+import org.apache.syncope.common.lib.types.TaskType;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
import org.apache.wicket.extensions.markup.html.tabs.ITab;
@@ -37,41 +40,43 @@ import org.apache.wicket.model.ResourceModel;
import org.apache.wicket.model.StringResourceModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;
-public class Reports extends BasePage {
+public class Engagements extends BasePage {
private static final long serialVersionUID = -1100228004207271271L;
- public Reports(final PageParameters parameters) {
+ public Engagements(final PageParameters parameters) {
super(parameters);
body.add(BookmarkablePageLinkBuilder.build("dashboard", "dashboardBr", Dashboard.class));
WebMarkupContainer content = new WebMarkupContainer("content");
content.setOutputMarkupId(true);
- content.setMarkupId("reports");
+ content.setMarkupId("engagements");
content.add(new AjaxBootstrapTabbedPanel<>("tabbedPanel", buildTabList()));
body.add(content);
}
private List<ITab> buildTabList() {
- final List<ITab> tabs = new ArrayList<>();
+ List<ITab> tabs = new ArrayList<>();
- tabs.add(new AbstractTab(new ResourceModel("reports")) {
+ tabs.add(new AbstractTab(new ResourceModel("schedTasks")) {
private static final long serialVersionUID = -6815067322125799251L;
@Override
public Panel getPanel(final String panelId) {
MultilevelPanel mlp = new MultilevelPanel(panelId);
- mlp.setFirstLevel(new ReportDirectoryPanel(getPageReference()) {
+ mlp.setFirstLevel(new SchedTaskDirectoryPanel<>(MultilevelPanel.FIRST_LEVEL_ID,
+ null, null, TaskType.SCHEDULED, new SchedTaskTO(), getPageReference(), true) {
private static final long serialVersionUID = -2195387360323687302L;
@Override
- protected void viewReport(final ReportTO reportTO, final AjaxRequestTarget target) {
+ protected void viewTaskExecs(final SchedTaskTO taskTO, final AjaxRequestTarget target) {
mlp.next(
- new StringResourceModel("report.view", this, new Model<>(reportTO)).getObject(),
- new ReportExecutionDetails(reportTO, getPageReference()),
+ new StringResourceModel(
+ "task.view", this, new Model<>(Pair.of(null, taskTO))).getObject(),
+ new TaskExecutionDetails<>(taskTO, pageRef),
target);
}
});
@@ -79,15 +84,28 @@ public class Reports extends BasePage {
}
});
- tabs.add(new AbstractTab(new ResourceModel("report.templates")) {
+ tabs.add(new AbstractTab(new ResourceModel("commands")) {
private static final long serialVersionUID = -6815067322125799251L;
@Override
public Panel getPanel(final String panelId) {
- return new ReportTemplateDirectoryPanel(panelId, getPageReference());
+ return new CommandsPanel(panelId, getPageReference());
}
});
+
+ tabs.add(new AbstractTab(new ResourceModel("macroTasks")) {
+
+ private static final long serialVersionUID = 5211692813425391144L;
+
+ @Override
+ public Panel getPanel(final String panelId) {
+ MultilevelPanel mlp = new MultilevelPanel(panelId);
+ mlp.setFirstLevel(new MacroTaskDirectoryPanel(mlp, getPageReference()));
+ return mlp;
+ }
+ });
+
return tabs;
}
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Reports.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Reports.java
index 46763162a2..d886d61a2d 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Reports.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Reports.java
@@ -54,7 +54,7 @@ public class Reports extends BasePage {
}
private List<ITab> buildTabList() {
- final List<ITab> tabs = new ArrayList<>();
+ List<ITab> tabs = new ArrayList<>();
tabs.add(new AbstractTab(new ResourceModel("reports")) {
@@ -68,7 +68,7 @@ public class Reports extends BasePage {
private static final long serialVersionUID = -2195387360323687302L;
@Override
- protected void viewReport(final ReportTO reportTO, final AjaxRequestTarget target) {
+ protected void viewReportExecs(final ReportTO reportTO, final AjaxRequestTarget target) {
mlp.next(
new StringResourceModel("report.view", this, new Model<>(reportTO)).getObject(),
new ReportExecutionDetails(reportTO, getPageReference()),
@@ -88,6 +88,7 @@ public class Reports extends BasePage {
return new ReportTemplateDirectoryPanel(panelId, getPageReference());
}
});
+
return tabs;
}
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel.java
index 22a7bd7ff7..2164a5fce9 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel.java
@@ -82,6 +82,7 @@ public class AccessTokenDirectoryPanel
@Override
protected List<IColumn<AccessTokenTO, String>> getColumns() {
List<IColumn<AccessTokenTO, String>> columns = new ArrayList<>();
+
columns.add(new KeyPropertyColumn<>(
new StringResourceModel(Constants.KEY_FIELD_NAME, this),
Constants.KEY_FIELD_NAME,
@@ -118,7 +119,7 @@ public class AccessTokenDirectoryPanel
@Override
public ActionsPanel<AccessTokenTO> getActions(final IModel<AccessTokenTO> model) {
- final ActionsPanel<AccessTokenTO> panel = super.getActions(model);
+ ActionsPanel<AccessTokenTO> panel = super.getActions(model);
panel.add(new ActionLink<>() {
@@ -146,7 +147,7 @@ public class AccessTokenDirectoryPanel
return List.of();
}
- public abstract static class Builder
+ public static class Builder
extends DirectoryPanel.Builder<AccessTokenTO, AccessTokenTO, AccessTokenRestClient> {
private static final long serialVersionUID = 5088962796986706805L;
@@ -165,8 +166,6 @@ public class AccessTokenDirectoryPanel
private static final long serialVersionUID = 6267494272884913376L;
- private final AccessTokenRestClient restClient = new AccessTokenRestClient();
-
public AccessTokenDataProvider(final int paginatorRows) {
super(paginatorRows);
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
index 2f9c72c581..343710b916 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
@@ -80,8 +80,6 @@ public final class AjaxDataTablePanel<T extends Serializable, S> extends DataTab
private MultilevelPanel multiLevelPanel;
- private BaseModal<?> baseModal;
-
public Builder(final ISortableDataProvider<T, S> provider, final PageReference pageRef) {
this.dataProvider = provider;
this.pageRef = pageRef;
@@ -152,9 +150,8 @@ public final class AjaxDataTablePanel<T extends Serializable, S> extends DataTab
return checkBoxEnabled && batchExecutor != null && !batches.isEmpty();
}
- public void setMultiLevelPanel(final BaseModal<?> baseModal, final MultilevelPanel multiLevelPanel) {
+ public void setMultiLevelPanel(final MultilevelPanel multiLevelPanel) {
this.multiLevelPanel = multiLevelPanel;
- this.baseModal = baseModal;
}
protected ActionsPanel<T> getActions(final IModel<T> model) {
@@ -213,7 +210,7 @@ public final class AjaxDataTablePanel<T extends Serializable, S> extends DataTab
}
dataTable = new AjaxFallbackDataTable<>(
- "dataTable", builder.columns, builder.dataProvider, builder.rowsPerPage, builder.container) {
+ "dataTable", builder.columns, builder.dataProvider, builder.rowsPerPage, builder.container) {
private static final long serialVersionUID = -7370603907251344224L;
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/CommandDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/CommandDirectoryPanel.java
new file mode 100644
index 0000000000..85322a8423
--- /dev/null
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/CommandDirectoryPanel.java
@@ -0,0 +1,190 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.commons.IdRepoConstants;
+import org.apache.syncope.client.console.commons.KeywordSearchEvent;
+import org.apache.syncope.client.console.panels.CommandDirectoryPanel.CommandDataProvider;
+import org.apache.syncope.client.console.rest.CommandRestClient;
+import org.apache.syncope.client.console.tasks.ExecMessage;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
+import org.apache.syncope.client.console.wizards.CommandWizardBuilder;
+import org.apache.syncope.client.ui.commons.Constants;
+import org.apache.syncope.client.ui.commons.DirectoryDataProvider;
+import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
+import org.apache.syncope.common.lib.command.CommandTO;
+import org.apache.syncope.common.lib.types.IdRepoEntitlement;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.event.Broadcast;
+import org.apache.wicket.event.IEvent;
+import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.ResourceModel;
+
+public class CommandDirectoryPanel
+ extends DirectoryPanel<CommandTO, CommandTO, CommandDataProvider, CommandRestClient> {
+
+ private static final long serialVersionUID = -8723262033772725592L;
+
+ private String keyword;
+
+ public CommandDirectoryPanel(final String id, final PageReference pageRef) {
+ super(id, pageRef);
+ disableCheckBoxes();
+
+ modal.size(Modal.Size.Large);
+
+ modal.setWindowClosedCallback(target -> {
+ updateResultTable(target);
+ modal.show(false);
+ });
+
+ addNewItemPanelBuilder(new CommandWizardBuilder(new CommandTO(), pageRef), false);
+
+ setShowResultPanel(true);
+
+ initResultTable();
+ }
+
+ @Override
+ protected CommandDataProvider dataProvider() {
+ return new CommandDataProvider(rows);
+ }
+
+ @Override
+ protected String paginatorRowsKey() {
+ return IdRepoConstants.PREF_COMMAND_PAGINATOR_ROWS;
+ }
+
+ @Override
+ protected List<IColumn<CommandTO, String>> getColumns() {
+ List<IColumn<CommandTO, String>> columns = new ArrayList<>();
+
+ columns.add(new PropertyColumn<>(
+ new ResourceModel(Constants.KEY_FIELD_NAME), Constants.KEY_FIELD_NAME, Constants.KEY_FIELD_NAME));
+
+ columns.add(new AbstractColumn<>(new ResourceModel("arguments"), "arguments") {
+
+ private static final long serialVersionUID = -4008579357070833846L;
+
+ @Override
+ public void populateItem(
+ final Item<ICellPopulator<CommandTO>> cellItem,
+ final String componentId,
+ final IModel<CommandTO> rowModel) {
+
+ cellItem.add(new Label(componentId, rowModel.getObject().getArgs().getClass().getName()));
+ }
+ });
+
+ return columns;
+ }
+
+ @Override
+ protected ActionsPanel<CommandTO> getActions(final IModel<CommandTO> model) {
+ ActionsPanel<CommandTO> panel = super.getActions(model);
+
+ panel.add(new ActionLink<>() {
+
+ private static final long serialVersionUID = -3722207913631435501L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final CommandTO ignore) {
+ send(CommandDirectoryPanel.this, Broadcast.EXACT,
+ new AjaxWizard.EditItemActionEvent<>(model.getObject(), target));
+ }
+ }, ActionLink.ActionType.EXECUTE, IdRepoEntitlement.COMMAND_RUN);
+
+ return panel;
+ }
+
+ @Override
+ protected Collection<ActionLink.ActionType> getBatches() {
+ return List.of();
+ }
+
+ @Override
+ protected Panel customResultBody(final String panelId, final CommandTO item, final Serializable result) {
+ return new ExecMessage(panelId, (String) result);
+ }
+
+ @Override
+ public void onEvent(final IEvent<?> event) {
+ if (event.getPayload() instanceof KeywordSearchEvent) {
+ KeywordSearchEvent payload = KeywordSearchEvent.class.cast(event.getPayload());
+
+ keyword = payload.getKeyword();
+ if (StringUtils.isNotBlank(keyword)) {
+ if (!StringUtils.startsWith(keyword, "*")) {
+ keyword = "*" + keyword;
+ }
+ if (!StringUtils.endsWith(keyword, "*")) {
+ keyword += "*";
+ }
+ }
+
+ updateResultTable(payload.getTarget());
+ } else {
+ super.onEvent(event);
+ }
+ }
+
+ protected final class CommandDataProvider extends DirectoryDataProvider<CommandTO> {
+
+ private static final long serialVersionUID = 6267494272884913376L;
+
+ public CommandDataProvider(final int paginatorRows) {
+ super(paginatorRows);
+ }
+
+ @Override
+ public Iterator<CommandTO> iterator(final long first, final long count) {
+ int page = ((int) first / paginatorRows);
+ return CommandRestClient.search(
+ (page < 0 ? 0 : page) + 1, paginatorRows, keyword).
+ iterator();
+ }
+
+ @Override
+ public long size() {
+ return CommandRestClient.count(keyword);
+ }
+
+ @Override
+ public IModel<CommandTO> model(final CommandTO object) {
+ return new CompoundPropertyModel<>(object);
+ }
+ }
+}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SchemasPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/CommandsPanel.java
similarity index 60%
copy from client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SchemasPanel.java
copy to client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/CommandsPanel.java
index 4cfcb573e2..f3e1f94eed 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SchemasPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/CommandsPanel.java
@@ -18,34 +18,25 @@
*/
package org.apache.syncope.client.console.panels;
-import java.util.ArrayList;
-import java.util.List;
import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.commons.KeywordSearchEvent;
import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
-import org.apache.syncope.client.ui.commons.wicket.markup.html.bootstrap.tabs.Accordion;
-import org.apache.syncope.common.lib.types.SchemaType;
import org.apache.wicket.PageReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.event.Broadcast;
-import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
-import org.apache.wicket.extensions.markup.html.tabs.ITab;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.Model;
-public class SchemasPanel extends Panel {
+public class CommandsPanel extends Panel {
- private static final long serialVersionUID = -1140213992451232279L;
+ private static final long serialVersionUID = -4716856239434102405L;
- private final PageReference pageRef;
-
- public SchemasPanel(final String id, final PageReference pageRef) {
+ public CommandsPanel(final String id, final PageReference pageRef) {
super(id);
- this.pageRef = pageRef;
-
Model<String> keywordModel = new Model<>(StringUtils.EMPTY);
WebMarkupContainer searchBoxContainer = new WebMarkupContainer("searchBox");
@@ -63,34 +54,13 @@ public class SchemasPanel extends Panel {
@Override
protected void onSubmit(final AjaxRequestTarget target) {
- send(SchemasPanel.this, Broadcast.DEPTH,
- new SchemaTypePanel.SchemaSearchEvent(target, keywordModel.getObject()));
+ send(CommandsPanel.this, Broadcast.DEPTH, new KeywordSearchEvent(target, keywordModel.getObject()));
}
};
search.setOutputMarkupId(true);
form.add(search);
form.setDefaultButton(search);
- Accordion accordion = new Accordion("accordionPanel", buildTabList());
- accordion.setOutputMarkupId(true);
- add(accordion);
- }
-
- private List<ITab> buildTabList() {
- List<ITab> tabs = new ArrayList<>();
-
- for (final SchemaType schemaType : SchemaType.values()) {
- tabs.add(new AbstractTab(new Model<>(schemaType.name())) {
-
- private static final long serialVersionUID = 1037272333056449378L;
-
- @Override
- public Panel getPanel(final String panelId) {
- return new SchemaTypePanel(panelId, schemaType, pageRef);
- }
- });
- }
-
- return tabs;
+ add(new CommandDirectoryPanel("commands", pageRef).setOutputMarkupId(true));
}
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DashboardAccessTokensPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DashboardAccessTokensPanel.java
index d9dcc89f9e..9cecc65985 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DashboardAccessTokensPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DashboardAccessTokensPanel.java
@@ -33,14 +33,10 @@ public class DashboardAccessTokensPanel extends Panel {
public DashboardAccessTokensPanel(final String id, final PageReference pageRef) {
super(id);
- WizardMgtPanel<AccessTokenTO> accessTokens = new AccessTokenDirectoryPanel.Builder(pageRef) {
-
- private static final long serialVersionUID = -5960765294082359003L;
-
- }.disableCheckBoxes().build("accessTokens");
+ WizardMgtPanel<AccessTokenTO> accessTokens = new AccessTokenDirectoryPanel.Builder(pageRef).
+ disableCheckBoxes().build("accessTokens");
MetaDataRoleAuthorizationStrategy.authorize(
accessTokens, Component.RENDER, IdRepoEntitlement.ACCESS_TOKEN_LIST);
add(accessTokens);
}
-
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ExecMessageModal.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ExecMessageModal.java
index 0b776699d9..589ae3e254 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ExecMessageModal.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ExecMessageModal.java
@@ -35,5 +35,4 @@ public class ExecMessageModal extends Panel implements ModalPanel {
super(id);
add(new Label("executionMessage", executionMessage).setOutputMarkupId(true));
}
-
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ImplementationModalPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ImplementationModalPanel.java
index 1e618537fa..bcd0f29284 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ImplementationModalPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ImplementationModalPanel.java
@@ -95,8 +95,8 @@ public class ImplementationModalPanel extends AbstractModalPanel<ImplementationT
if (viewMode == ViewMode.JSON_BODY && StringUtils.isNotBlank(implementation.getBody())) {
try {
JsonNode node = MAPPER.readTree(implementation.getBody());
- if (node.has("@class")) {
- jsonClass.setModelObject(node.get("@class").asText());
+ if (node.has("_class")) {
+ jsonClass.setModelObject(node.get("_class").asText());
}
} catch (IOException e) {
LOG.error("Could not parse as JSON payload: {}", implementation.getBody(), e);
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ModalDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ModalDirectoryPanel.java
index 6d524c537c..bddd1bf790 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ModalDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ModalDirectoryPanel.java
@@ -24,7 +24,7 @@ import org.apache.wicket.PageReference;
public class ModalDirectoryPanel<T extends Serializable> extends AbstractModalPanel<T> {
- private static final long serialVersionUID = 1L;
+ private static final long serialVersionUID = -2882969833580638049L;
public ModalDirectoryPanel(
final BaseModal<T> modal, final DirectoryPanel<?, ?, ?, ?> directoryPanel, final PageReference pageRef) {
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypePanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypePanel.java
index f087da2afa..4e839eef26 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypePanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypePanel.java
@@ -18,7 +18,6 @@
*/
package org.apache.syncope.client.console.panels;
-import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
@@ -28,6 +27,7 @@ import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.client.console.SyncopeConsoleSession;
import org.apache.syncope.client.console.commons.IdRepoConstants;
+import org.apache.syncope.client.console.commons.KeywordSearchEvent;
import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
import org.apache.syncope.client.console.pages.BasePage;
import org.apache.syncope.client.console.panels.SchemaTypePanel.SchemaProvider;
@@ -184,6 +184,27 @@ public class SchemaTypePanel extends TypesDirectoryPanel<SchemaTO, SchemaProvide
return panel;
}
+ @Override
+ public void onEvent(final IEvent<?> event) {
+ if (event.getPayload() instanceof KeywordSearchEvent) {
+ KeywordSearchEvent payload = KeywordSearchEvent.class.cast(event.getPayload());
+
+ keyword = payload.getKeyword();
+ if (StringUtils.isNotBlank(keyword)) {
+ if (!StringUtils.startsWith(keyword, "*")) {
+ keyword = "*" + keyword;
+ }
+ if (!StringUtils.endsWith(keyword, "*")) {
+ keyword += "*";
+ }
+ }
+
+ updateResultTable(payload.getTarget());
+ } else {
+ super.onEvent(event);
+ }
+ }
+
protected final class SchemaProvider extends DirectoryDataProvider<SchemaTO> {
private static final long serialVersionUID = -185944053385660794L;
@@ -218,48 +239,4 @@ public class SchemaTypePanel extends TypesDirectoryPanel<SchemaTO, SchemaProvide
return new CompoundPropertyModel<>(object);
}
}
-
- @Override
- public void onEvent(final IEvent<?> event) {
- if (event.getPayload() instanceof SchemaSearchEvent) {
- SchemaSearchEvent payload = SchemaSearchEvent.class.cast(event.getPayload());
- AjaxRequestTarget target = payload.getTarget();
-
- keyword = payload.getKeyword();
- if (StringUtils.isNotBlank(keyword)) {
- if (!StringUtils.startsWith(keyword, "*")) {
- keyword = "*" + keyword;
- }
- if (!StringUtils.endsWith(keyword, "*")) {
- keyword += "*";
- }
- }
-
- updateResultTable(target);
- } else {
- super.onEvent(event);
- }
- }
-
- public static class SchemaSearchEvent implements Serializable {
-
- private static final long serialVersionUID = -282052400565266028L;
-
- private final AjaxRequestTarget target;
-
- private final String keyword;
-
- SchemaSearchEvent(final AjaxRequestTarget target, final String keyword) {
- this.target = target;
- this.keyword = keyword;
- }
-
- public AjaxRequestTarget getTarget() {
- return target;
- }
-
- public String getKeyword() {
- return keyword;
- }
- }
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SchemasPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SchemasPanel.java
index 4cfcb573e2..1bbd5229b8 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SchemasPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SchemasPanel.java
@@ -21,6 +21,7 @@ package org.apache.syncope.client.console.panels;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.commons.KeywordSearchEvent;
import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
import org.apache.syncope.client.ui.commons.wicket.markup.html.bootstrap.tabs.Accordion;
import org.apache.syncope.common.lib.types.SchemaType;
@@ -63,8 +64,7 @@ public class SchemasPanel extends Panel {
@Override
protected void onSubmit(final AjaxRequestTarget target) {
- send(SchemasPanel.this, Broadcast.DEPTH,
- new SchemaTypePanel.SchemaSearchEvent(target, keywordModel.getObject()));
+ send(SchemasPanel.this, Broadcast.DEPTH, new KeywordSearchEvent(target, keywordModel.getObject()));
}
};
search.setOutputMarkupId(true);
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/policies/PolicyRuleDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/policies/PolicyRuleDirectoryPanel.java
index 48904d3bbc..0692cb4a71 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/policies/PolicyRuleDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/policies/PolicyRuleDirectoryPanel.java
@@ -108,21 +108,21 @@ public class PolicyRuleDirectoryPanel<T extends PolicyTO> extends DirectoryPanel
@Override
protected List<IColumn<PolicyRuleWrapper, String>> getColumns() {
- final List<IColumn<PolicyRuleWrapper, String>> columns = new ArrayList<>();
+ List<IColumn<PolicyRuleWrapper, String>> columns = new ArrayList<>();
columns.add(new PropertyColumn<>(
new StringResourceModel("rule", this), "implementationKey", "implementationKey"));
columns.add(new AbstractColumn<>(
- new StringResourceModel("configuration", this)) {
+ new StringResourceModel("configuration", this)) {
private static final long serialVersionUID = -4008579357070833846L;
@Override
public void populateItem(
- final Item<ICellPopulator<PolicyRuleWrapper>> cellItem,
- final String componentId,
- final IModel<PolicyRuleWrapper> rowModel) {
+ final Item<ICellPopulator<PolicyRuleWrapper>> cellItem,
+ final String componentId,
+ final IModel<PolicyRuleWrapper> rowModel) {
if (rowModel.getObject().getConf() == null) {
cellItem.add(new Label(componentId, ""));
@@ -131,6 +131,7 @@ public class PolicyRuleDirectoryPanel<T extends PolicyTO> extends DirectoryPanel
}
}
});
+
return columns;
}
@@ -150,10 +151,11 @@ public class PolicyRuleDirectoryPanel<T extends PolicyTO> extends DirectoryPanel
((BaseWebPage) pageRef.getPage()).getNotificationPanel().refresh(target);
} else {
send(PolicyRuleDirectoryPanel.this, Broadcast.EXACT,
- new AjaxWizard.EditItemActionEvent<>(model.getObject(), target));
+ new AjaxWizard.EditItemActionEvent<>(model.getObject(), target));
}
}
}, ActionLink.ActionType.EDIT, IdRepoEntitlement.POLICY_UPDATE);
+
panel.add(new ActionLink<>() {
private static final long serialVersionUID = -3722207913631435501L;
@@ -183,7 +185,7 @@ public class PolicyRuleDirectoryPanel<T extends PolicyTO> extends DirectoryPanel
@Override
public ActionsPanel<Serializable> getHeader(final String componentId) {
- final ActionsPanel<Serializable> panel = new ActionsPanel<>(componentId, null);
+ ActionsPanel<Serializable> panel = new ActionsPanel<>(componentId, null);
panel.add(new ActionLink<>() {
@@ -196,6 +198,7 @@ public class PolicyRuleDirectoryPanel<T extends PolicyTO> extends DirectoryPanel
}
}
}, ActionLink.ActionType.RELOAD, IdRepoEntitlement.POLICY_LIST).hideLabel();
+
return panel;
}
@@ -251,7 +254,7 @@ public class PolicyRuleDirectoryPanel<T extends PolicyTO> extends DirectoryPanel
@Override
public Iterator<PolicyRuleWrapper> iterator(final long first, final long count) {
- final T actual = PolicyRestClient.read(type, policy);
+ T actual = PolicyRestClient.read(type, policy);
List<PolicyRuleWrapper> rules = actual instanceof ComposablePolicy
? getPolicyRuleWrappers((ComposablePolicy) actual)
@@ -263,7 +266,7 @@ public class PolicyRuleDirectoryPanel<T extends PolicyTO> extends DirectoryPanel
@Override
public long size() {
- final T actual = PolicyRestClient.read(type, policy);
+ T actual = PolicyRestClient.read(type, policy);
return actual instanceof ComposablePolicy
? getPolicyRuleWrappers((ComposablePolicy) actual).size()
: 0;
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/policies/PolicyRuleWizardBuilder.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/policies/PolicyRuleWizardBuilder.java
index 4a031a5638..b4fa3e11c5 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/policies/PolicyRuleWizardBuilder.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/policies/PolicyRuleWizardBuilder.java
@@ -118,7 +118,7 @@ public class PolicyRuleWizardBuilder extends BaseAjaxWizardBuilder<PolicyRuleWra
public Profile(final PolicyRuleWrapper rule) {
this.rule = rule;
- final AjaxDropDownChoicePanel<String> conf = new AjaxDropDownChoicePanel<>(
+ AjaxDropDownChoicePanel<String> conf = new AjaxDropDownChoicePanel<>(
"rule", "rule", new PropertyModel<>(rule, "implementationKey"));
List<String> choices;
@@ -151,8 +151,7 @@ public class PolicyRuleWizardBuilder extends BaseAjaxWizardBuilder<PolicyRuleWra
rule.setImplementationEngine(impl.getEngine());
if (impl.getEngine() == ImplementationEngine.JAVA) {
try {
- RuleConf ruleConf = MAPPER.readValue(impl.getBody(), RuleConf.class);
- rule.setConf(ruleConf);
+ rule.setConf(MAPPER.readValue(impl.getBody(), RuleConf.class));
} catch (Exception e) {
LOG.error("During deserialization", e);
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportDirectoryPanel.java
index 1c3375ddd2..4bd232851d 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportDirectoryPanel.java
@@ -79,9 +79,9 @@ public abstract class ReportDirectoryPanel
protected ReportDirectoryPanel(final PageReference pageRef) {
super(MultilevelPanel.FIRST_LEVEL_ID, pageRef, true);
- this.restClient = new ReportRestClient();
+ restClient = new ReportRestClient();
- this.addNewItemPanelBuilder(new ReportWizardBuilder(new ReportTO(), pageRef), true);
+ addNewItemPanelBuilder(new ReportWizardBuilder(new ReportTO(), pageRef), true);
MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, RENDER, IdRepoEntitlement.REPORT_CREATE);
modal.size(Modal.Size.Large);
@@ -104,7 +104,7 @@ public abstract class ReportDirectoryPanel
@Override
protected List<IColumn<ReportTO, String>> getColumns() {
- final List<IColumn<ReportTO, String>> columns = new ArrayList<>();
+ List<IColumn<ReportTO, String>> columns = new ArrayList<>();
columns.add(new KeyPropertyColumn<>(
new StringResourceModel(Constants.KEY_FIELD_NAME, this), Constants.KEY_FIELD_NAME));
@@ -135,18 +135,18 @@ public abstract class ReportDirectoryPanel
@Override
public void populateItem(
- final Item<ICellPopulator<ReportTO>> cellItem,
- final String componentId,
- final IModel<ReportTO> rowModel) {
+ final Item<ICellPopulator<ReportTO>> cellItem,
+ final String componentId,
+ final IModel<ReportTO> rowModel) {
Component panel;
try {
JobTO jobTO = ReportRestClient.getJob(rowModel.getObject().getKey());
panel = new JobActionPanel(componentId, jobTO, false, ReportDirectoryPanel.this);
MetaDataRoleAuthorizationStrategy.authorize(panel, WebPage.ENABLE,
- String.format("%s,%s",
- IdRepoEntitlement.REPORT_EXECUTE,
- IdRepoEntitlement.REPORT_UPDATE));
+ String.format("%s,%s",
+ IdRepoEntitlement.REPORT_EXECUTE,
+ IdRepoEntitlement.REPORT_UPDATE));
} catch (Exception e) {
LOG.error("Could not get job for report {}", rowModel.getObject().getKey(), e);
panel = new Label(componentId, Model.of());
@@ -156,7 +156,7 @@ public abstract class ReportDirectoryPanel
@Override
public String getCssClass() {
- return "col-xs-1";
+ return "running-col";
}
});
@@ -175,7 +175,17 @@ public abstract class ReportDirectoryPanel
@Override
public ActionsPanel<ReportTO> getActions(final IModel<ReportTO> model) {
- final ActionsPanel<ReportTO> panel = super.getActions(model);
+ ActionsPanel<ReportTO> panel = super.getActions(model);
+
+ panel.add(new ActionLink<>() {
+
+ private static final long serialVersionUID = -3722207913631435501L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final ReportTO ignore) {
+ viewReportExecs(model.getObject(), target);
+ }
+ }, ActionLink.ActionType.VIEW_EXECUTIONS, IdRepoEntitlement.REPORT_READ);
panel.add(new ActionLink<>() {
@@ -184,8 +194,8 @@ public abstract class ReportDirectoryPanel
@Override
public void onClick(final AjaxRequestTarget target, final ReportTO ignore) {
send(ReportDirectoryPanel.this, Broadcast.EXACT,
- new AjaxWizard.EditItemActionEvent<>(
- ReportRestClient.read(model.getObject().getKey()), target));
+ new AjaxWizard.EditItemActionEvent<>(
+ ReportRestClient.read(model.getObject().getKey()), target));
}
}, ActionLink.ActionType.EDIT, IdRepoEntitlement.REPORT_UPDATE);
@@ -198,7 +208,7 @@ public abstract class ReportDirectoryPanel
final ReportTO clone = SerializationUtils.clone(model.getObject());
clone.setKey(null);
send(ReportDirectoryPanel.this, Broadcast.EXACT,
- new AjaxWizard.EditItemActionEvent<>(clone, target));
+ new AjaxWizard.EditItemActionEvent<>(clone, target));
}
}, ActionLink.ActionType.CLONE, IdRepoEntitlement.REPORT_CREATE);
@@ -208,25 +218,14 @@ public abstract class ReportDirectoryPanel
@Override
public void onClick(final AjaxRequestTarget target, final ReportTO ignore) {
- target.add(modal.setContent(new ReportletDirectoryPanel(
- modal, model.getObject().getKey(), pageRef)));
+ target.add(modal.setContent(new ReportletDirectoryPanel(modal, model.getObject().getKey(), pageRef)));
modal.header(new StringResourceModel(
- "reportlet.conf", ReportDirectoryPanel.this, Model.of(model.getObject())));
+ "reportlet.conf", ReportDirectoryPanel.this, Model.of(model.getObject())));
modal.show(true);
}
}, ActionLink.ActionType.COMPOSE, IdRepoEntitlement.REPORT_UPDATE);
- panel.add(new ActionLink<>() {
-
- private static final long serialVersionUID = -3722207913631435501L;
-
- @Override
- public void onClick(final AjaxRequestTarget target, final ReportTO ignore) {
- viewReport(model.getObject(), target);
- }
- }, ActionLink.ActionType.VIEW_EXECUTIONS, IdRepoEntitlement.REPORT_READ);
-
panel.add(new ActionLink<>() {
private static final long serialVersionUID = -3722207913631435501L;
@@ -234,7 +233,7 @@ public abstract class ReportDirectoryPanel
@Override
public void onClick(final AjaxRequestTarget target, final ReportTO ignore) {
startAt.setExecutionDetail(
- model.getObject().getKey(), model.getObject().getName(), target);
+ model.getObject().getKey(), model.getObject().getName(), target);
startAt.toggle(target, true);
}
}, ActionLink.ActionType.EXECUTE, IdRepoEntitlement.REPORT_EXECUTE);
@@ -257,6 +256,7 @@ public abstract class ReportDirectoryPanel
((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
}
}, ActionLink.ActionType.DELETE, IdRepoEntitlement.REPORT_DELETE, true);
+
return panel;
}
@@ -278,7 +278,7 @@ public abstract class ReportDirectoryPanel
return IdRepoConstants.PREF_REPORT_PAGINATOR_ROWS;
}
- protected abstract void viewReport(ReportTO reportTO, AjaxRequestTarget target);
+ protected abstract void viewReportExecs(ReportTO reportTO, AjaxRequestTarget target);
protected static class ReportDataProvider extends DirectoryDataProvider<ReportTO> {
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportExecutionDetails.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportExecutionDetails.java
index fb7246743e..66cad1a013 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportExecutionDetails.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportExecutionDetails.java
@@ -44,7 +44,7 @@ public class ReportExecutionDetails extends MultilevelPanel.SecondLevel {
public ReportExecutionDetails(final ReportTO reportTO, final PageReference pageRef) {
super();
- final MultilevelPanel mlp = new MultilevelPanel("executions");
+ MultilevelPanel mlp = new MultilevelPanel("executions");
add(mlp);
mlp.setFirstLevel(new ReportExecutionDirectoryPanel(mlp, reportTO.getKey(), new ReportRestClient(), pageRef));
@@ -54,8 +54,6 @@ public class ReportExecutionDetails extends MultilevelPanel.SecondLevel {
private static final long serialVersionUID = 5691719817252887541L;
- private final MultilevelPanel mlp;
-
private final AjaxDownloadBehavior downloadBehavior;
ReportExecutionDirectoryPanel(
@@ -63,8 +61,8 @@ public class ReportExecutionDetails extends MultilevelPanel.SecondLevel {
final String key,
final ExecutionRestClient executionRestClient,
final PageReference pageRef) {
+
super(multiLevelPanelRef, key, executionRestClient, pageRef);
- this.mlp = multiLevelPanelRef;
this.downloadBehavior = new AjaxDownloadBehavior();
this.add(downloadBehavior);
@@ -75,7 +73,8 @@ public class ReportExecutionDetails extends MultilevelPanel.SecondLevel {
final String title,
final MultilevelPanel.SecondLevel slevel,
final AjaxRequestTarget target) {
- mlp.next(title, slevel, target);
+
+ multiLevelPanelRef.next(title, slevel, target);
}
@Override
@@ -87,7 +86,7 @@ public class ReportExecutionDetails extends MultilevelPanel.SecondLevel {
@Override
public void onClick(final AjaxRequestTarget target, final ExecTO ignore) {
downloadBehavior.setResponse(new ResponseHolder(ReportRestClient.exportExecutionResult(
- model.getObject().getKey(), ReportExecExportFormat.CSV)));
+ model.getObject().getKey(), ReportExecExportFormat.CSV)));
downloadBehavior.initiate(target);
}
}, ActionLink.ActionType.EXPORT_CSV, IdRepoEntitlement.REPORT_READ);
@@ -99,7 +98,7 @@ public class ReportExecutionDetails extends MultilevelPanel.SecondLevel {
@Override
public void onClick(final AjaxRequestTarget target, final ExecTO ignore) {
downloadBehavior.setResponse(new ResponseHolder(ReportRestClient.exportExecutionResult(
- model.getObject().getKey(), ReportExecExportFormat.HTML)));
+ model.getObject().getKey(), ReportExecExportFormat.HTML)));
downloadBehavior.initiate(target);
}
}, ActionLink.ActionType.EXPORT_HTML, IdRepoEntitlement.REPORT_READ);
@@ -111,7 +110,7 @@ public class ReportExecutionDetails extends MultilevelPanel.SecondLevel {
@Override
public void onClick(final AjaxRequestTarget target, final ExecTO ignore) {
downloadBehavior.setResponse(new ResponseHolder(ReportRestClient.exportExecutionResult(
- model.getObject().getKey(), ReportExecExportFormat.PDF)));
+ model.getObject().getKey(), ReportExecExportFormat.PDF)));
downloadBehavior.initiate(target);
}
}, ActionLink.ActionType.EXPORT_PDF, IdRepoEntitlement.REPORT_READ);
@@ -123,7 +122,7 @@ public class ReportExecutionDetails extends MultilevelPanel.SecondLevel {
@Override
public void onClick(final AjaxRequestTarget target, final ExecTO ignore) {
downloadBehavior.setResponse(new ResponseHolder(ReportRestClient.exportExecutionResult(
- model.getObject().getKey(), ReportExecExportFormat.RTF)));
+ model.getObject().getKey(), ReportExecExportFormat.RTF)));
downloadBehavior.initiate(target);
}
}, ActionLink.ActionType.EXPORT_RTF, IdRepoEntitlement.REPORT_READ);
@@ -135,7 +134,7 @@ public class ReportExecutionDetails extends MultilevelPanel.SecondLevel {
@Override
public void onClick(final AjaxRequestTarget target, final ExecTO ignore) {
downloadBehavior.setResponse(new ResponseHolder(ReportRestClient.exportExecutionResult(
- model.getObject().getKey(), ReportExecExportFormat.XML)));
+ model.getObject().getKey(), ReportExecExportFormat.XML)));
downloadBehavior.initiate(target);
}
}, ActionLink.ActionType.EXPORT_XML, IdRepoEntitlement.REPORT_READ);
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportletDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportletDirectoryPanel.java
index 9bd23ea6f4..921061bc7e 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportletDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportletDirectoryPanel.java
@@ -78,6 +78,7 @@ public class ReportletDirectoryPanel extends DirectoryPanel<
public ReportletDirectoryPanel(
final BaseModal<ReportTO> baseModal, final String report, final PageReference pageRef) {
+
super(BaseModal.CONTENT_ID, pageRef, false);
disableCheckBoxes();
@@ -88,8 +89,7 @@ public class ReportletDirectoryPanel extends DirectoryPanel<
enableUtilityButton();
- this.addNewItemPanelBuilder(
- new ReportletWizardBuilder(report, new ReportletWrapper(true), pageRef), true);
+ addNewItemPanelBuilder(new ReportletWizardBuilder(report, new ReportletWrapper(true), pageRef), true);
MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, RENDER, IdRepoEntitlement.REPORT_UPDATE);
initResultTable();
@@ -103,15 +103,15 @@ public class ReportletDirectoryPanel extends DirectoryPanel<
new StringResourceModel("reportlet", this), "implementationKey", "implementationKey"));
columns.add(new AbstractColumn<>(
- new StringResourceModel("configuration", this)) {
+ new StringResourceModel("configuration", this)) {
private static final long serialVersionUID = -4008579357070833846L;
@Override
public void populateItem(
- final Item<ICellPopulator<ReportletWrapper>> cellItem,
- final String componentId,
- final IModel<ReportletWrapper> rowModel) {
+ final Item<ICellPopulator<ReportletWrapper>> cellItem,
+ final String componentId,
+ final IModel<ReportletWrapper> rowModel) {
if (rowModel.getObject().getConf() == null) {
cellItem.add(new Label(componentId, ""));
@@ -139,17 +139,18 @@ public class ReportletDirectoryPanel extends DirectoryPanel<
SyncopeConsoleSession.get().info(getString("noConf"));
} else {
send(ReportletDirectoryPanel.this, Broadcast.EXACT,
- new AjaxWizard.EditItemActionEvent<>(model.getObject(), target));
+ new AjaxWizard.EditItemActionEvent<>(model.getObject(), target));
}
}
}, ActionLink.ActionType.EDIT, IdRepoEntitlement.REPORT_UPDATE);
+
panel.add(new ActionLink<>() {
private static final long serialVersionUID = -3722207913631435501L;
@Override
public void onClick(final AjaxRequestTarget target, final ReportletWrapper ignore) {
- final ReportletConf reportlet = model.getObject().getConf();
+ ReportletConf reportlet = model.getObject().getConf();
try {
ReportTO actual = ReportRestClient.read(report);
actual.getReportlets().remove(model.getObject().getImplementationKey());
@@ -170,7 +171,7 @@ public class ReportletDirectoryPanel extends DirectoryPanel<
@Override
public ActionsPanel<Serializable> getHeader(final String componentId) {
- final ActionsPanel<Serializable> panel = new ActionsPanel<>(componentId, null);
+ ActionsPanel<Serializable> panel = new ActionsPanel<>(componentId, null);
panel.add(new ActionLink<>() {
@@ -182,7 +183,7 @@ public class ReportletDirectoryPanel extends DirectoryPanel<
customActionOnFinishCallback(target);
}
}
- }, ActionLink.ActionType.RELOAD, IdRepoEntitlement.TASK_LIST).hideLabel();
+ }, ActionLink.ActionType.RELOAD, IdRepoEntitlement.REPORT_READ).hideLabel();
return panel;
}
@@ -201,6 +202,16 @@ public class ReportletDirectoryPanel extends DirectoryPanel<
return IdRepoConstants.PREF_REPORTLET_PAGINATOR_ROWS;
}
+ @Override
+ public void onEvent(final IEvent<?> event) {
+ super.onEvent(event);
+ if (event.getPayload() instanceof ExitEvent) {
+ AjaxRequestTarget target = ExitEvent.class.cast(event.getPayload()).getTarget();
+ baseModal.show(false);
+ baseModal.close(target);
+ }
+ }
+
protected class ReportDataProvider extends DirectoryDataProvider<ReportletWrapper> {
private static final long serialVersionUID = 4725679400450513556L;
@@ -247,7 +258,7 @@ public class ReportletDirectoryPanel extends DirectoryPanel<
@Override
public long size() {
- final ReportTO actual = ReportRestClient.read(report);
+ ReportTO actual = ReportRestClient.read(report);
return getReportletWrappers(actual).size();
}
@@ -256,14 +267,4 @@ public class ReportletDirectoryPanel extends DirectoryPanel<
return new CompoundPropertyModel<>(object);
}
}
-
- @Override
- public void onEvent(final IEvent<?> event) {
- super.onEvent(event);
- if (event.getPayload() instanceof ExitEvent) {
- AjaxRequestTarget target = ExitEvent.class.cast(event.getPayload()).getTarget();
- baseModal.show(false);
- baseModal.close(target);
- }
- }
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportletWizardBuilder.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportletWizardBuilder.java
index 74f7be7664..0339e88557 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportletWizardBuilder.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportletWizardBuilder.java
@@ -20,6 +20,7 @@ package org.apache.syncope.client.console.reports;
import com.fasterxml.jackson.databind.json.JsonMapper;
import java.io.Serializable;
+import java.util.List;
import java.util.stream.Collectors;
import org.apache.syncope.client.console.panels.BeanPanel;
import org.apache.syncope.client.console.panels.search.SearchUtils;
@@ -50,6 +51,16 @@ public class ReportletWizardBuilder extends BaseAjaxWizardBuilder<ReportletWrapp
private static final JsonMapper MAPPER = JsonMapper.builder().findAndAddModules().build();
+ private final LoadableDetachableModel<List<ImplementationTO>> reportlets = new LoadableDetachableModel<>() {
+
+ private static final long serialVersionUID = 4659376149825914247L;
+
+ @Override
+ protected List<ImplementationTO> load() {
+ return ImplementationRestClient.list(IdRepoImplementationType.REPORTLET);
+ }
+ };
+
private final String report;
public ReportletWizardBuilder(final String report, final ReportletWrapper reportlet, final PageReference pageRef) {
@@ -63,14 +74,17 @@ public class ReportletWizardBuilder extends BaseAjaxWizardBuilder<ReportletWrapp
BeanWrapper confWrapper = PropertyAccessorFactory.forBeanPropertyAccess(modelObject.getConf());
modelObject.getSCondWrapper().forEach((fieldName, pair) -> confWrapper.setPropertyValue(
fieldName, SearchUtils.buildFIQL(pair.getRight(), pair.getLeft())));
- ImplementationTO reportlet = ImplementationRestClient.read(
- IdRepoImplementationType.REPORTLET, modelObject.getImplementationKey());
- try {
- reportlet.setBody(MAPPER.writeValueAsString(modelObject.getConf()));
- ImplementationRestClient.update(reportlet);
- } catch (Exception e) {
- throw new WicketRuntimeException(e);
- }
+ reportlets.getObject().stream().
+ filter(r -> r.getKey().equals(modelObject.getImplementationKey())).
+ findFirst().
+ ifPresent(reportlet -> {
+ try {
+ reportlet.setBody(MAPPER.writeValueAsString(modelObject.getConf()));
+ ImplementationRestClient.update(reportlet);
+ } catch (Exception e) {
+ throw new WicketRuntimeException(e);
+ }
+ });
}
ReportTO reportTO = ReportRestClient.read(report);
@@ -89,15 +103,19 @@ public class ReportletWizardBuilder extends BaseAjaxWizardBuilder<ReportletWrapp
return wizardModel;
}
- public static class Profile extends WizardStep {
+ public class Profile extends WizardStep {
private static final long serialVersionUID = -3043839139187792810L;
+ private final ReportletWrapper reportlet;
+
public Profile(final ReportletWrapper reportlet) {
+ this.reportlet = reportlet;
+
AjaxDropDownChoicePanel<String> conf = new AjaxDropDownChoicePanel<>(
"reportlet", getString("reportlet"), new PropertyModel<>(reportlet, "implementationKey"));
- conf.setChoices(ImplementationRestClient.list(IdRepoImplementationType.REPORTLET).stream().
+ conf.setChoices(reportlets.getObject().stream().
map(ImplementationTO::getKey).sorted().collect(Collectors.toList()));
conf.addRequiredLabel();
conf.setNullValid(false);
@@ -108,21 +126,30 @@ public class ReportletWizardBuilder extends BaseAjaxWizardBuilder<ReportletWrapp
@Override
protected void onEvent(final AjaxRequestTarget target) {
- ImplementationTO impl = ImplementationRestClient.read(
- IdRepoImplementationType.REPORTLET, conf.getModelObject());
- reportlet.setImplementationEngine(impl.getEngine());
- if (impl.getEngine() == ImplementationEngine.JAVA) {
- try {
- ReportletConf conf = MAPPER.readValue(impl.getBody(), ReportletConf.class);
- reportlet.setConf(conf);
- } catch (Exception e) {
- LOG.error("During deserialization", e);
- }
- }
+ reportlets.getObject().stream().
+ filter(r -> r.getKey().equals(conf.getModelObject())).
+ findFirst().
+ ifPresent(impl -> {
+ reportlet.setImplementationEngine(impl.getEngine());
+ if (impl.getEngine() == ImplementationEngine.JAVA) {
+ try {
+ reportlet.setConf(MAPPER.readValue(impl.getBody(), ReportletConf.class));
+ } catch (Exception e) {
+ LOG.error("During deserialization", e);
+ }
+ }
+ });
}
});
add(conf);
}
+
+ @Override
+ public void applyState() {
+ if (reportlet.getImplementationEngine() == ImplementationEngine.GROOVY) {
+ getWizardModel().finish();
+ }
+ }
}
public class Configuration extends WizardStep {
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/AccessTokenRestClient.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/AccessTokenRestClient.java
index ed95b43653..df311a4f3c 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/AccessTokenRestClient.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/AccessTokenRestClient.java
@@ -46,5 +46,4 @@ public class AccessTokenRestClient extends BaseRestClient {
new AccessTokenQuery.Builder().page(page).size(size).orderBy(toOrderBy(sort)).build()).
getResult();
}
-
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/CommandRestClient.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/CommandRestClient.java
new file mode 100644
index 0000000000..d11aa166be
--- /dev/null
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/CommandRestClient.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.rest;
+
+import java.util.List;
+import org.apache.syncope.common.lib.command.CommandOutput;
+import org.apache.syncope.common.lib.command.CommandTO;
+import org.apache.syncope.common.rest.api.beans.CommandQuery;
+import org.apache.syncope.common.rest.api.service.CommandService;
+
+public class CommandRestClient extends BaseRestClient {
+
+ private static final long serialVersionUID = -3582864276979370967L;
+
+ public static int count(final String keyword) {
+ return getService(CommandService.class).
+ search(new CommandQuery.Builder().page(1).size(0).keyword(keyword).build()).
+ getTotalCount();
+ }
+
+ public static List<CommandTO> search(final int page, final int size, final String keyword) {
+ return getService(CommandService.class).
+ search(new CommandQuery.Builder().page(page).size(size).keyword(keyword).build()).
+ getResult();
+ }
+
+ public static CommandTO read(final String key) {
+ return getService(CommandService.class).read(key);
+ }
+
+ public static CommandOutput run(final CommandTO command) {
+ return getService(CommandService.class).run(command);
+ }
+}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java
index 4719f33f4c..604954da7e 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java
@@ -32,8 +32,6 @@ import org.apache.syncope.common.lib.to.JobTO;
import org.apache.syncope.common.lib.to.NotificationTaskTO;
import org.apache.syncope.common.lib.to.PagedResult;
import org.apache.syncope.common.lib.to.PropagationTaskTO;
-import org.apache.syncope.common.lib.to.PullTaskTO;
-import org.apache.syncope.common.lib.to.PushTaskTO;
import org.apache.syncope.common.lib.to.SchedTaskTO;
import org.apache.syncope.common.lib.to.TaskTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
@@ -144,26 +142,33 @@ public class TaskRestClient extends BaseRestClient implements ExecutionRestClien
return list.getResult();
}
- @SuppressWarnings("unchecked")
public static <T extends TaskTO> List<T> list(
- final Class<T> reference, final int page, final int size, final SortParam<String> sort) {
-
- return (List<T>) getService(TaskService.class).
- search(new TaskQuery.Builder(getTaskType(reference)).page(page).size(size).
- orderBy(toOrderBy(sort)).build()).getResult();
+ final TaskType taskType, final int page, final int size, final SortParam<String> sort) {
+
+ return getService(TaskService.class).<T>search(
+ new TaskQuery.Builder(taskType).
+ page(page).
+ size(size).
+ orderBy(toOrderBy(sort)).
+ build()).
+ getResult();
}
- @SuppressWarnings("unchecked")
public static <T extends TaskTO> List<T> list(
final String resource,
- final Class<T> reference,
+ final TaskType taskType,
final int page,
final int size,
final SortParam<String> sort) {
- return (List<T>) getService(TaskService.class).
- search(new TaskQuery.Builder(getTaskType(reference)).page(page).size(size).resource(resource).
- orderBy(toOrderBy(sort)).build()).getResult();
+ return getService(TaskService.class).<T>search(
+ new TaskQuery.Builder(taskType).
+ page(page).
+ size(size).
+ resource(resource).
+ orderBy(toOrderBy(sort)).
+ build()).
+ getResult();
}
@Override
@@ -175,22 +180,6 @@ public class TaskRestClient extends BaseRestClient implements ExecutionRestClien
orderBy(toOrderBy(sort)).build()).getResult();
}
- private static TaskType getTaskType(final Class<?> reference) {
- TaskType result = null;
- if (PropagationTaskTO.class.equals(reference)) {
- result = TaskType.PROPAGATION;
- } else if (NotificationTaskTO.class.equals(reference)) {
- result = TaskType.NOTIFICATION;
- } else if (SchedTaskTO.class.equals(reference)) {
- result = TaskType.SCHEDULED;
- } else if (PullTaskTO.class.equals(reference)) {
- result = TaskType.PULL;
- } else if (PushTaskTO.class.equals(reference)) {
- result = TaskType.PUSH;
- }
- return result;
- }
-
public static PropagationTaskTO readPropagationTask(final String taskKey) {
return getService(TaskService.class).read(TaskType.PROPAGATION, taskKey, false);
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/AnyPropagationTasks.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/AnyPropagationTasks.java
index 7caf80cca9..de56660737 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/AnyPropagationTasks.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/AnyPropagationTasks.java
@@ -47,10 +47,10 @@ public class AnyPropagationTasks extends AbstractPropagationTasks {
private static final long serialVersionUID = -2195387360323687302L;
@Override
- protected void viewTask(final PropagationTaskTO taskTO, final AjaxRequestTarget target) {
+ protected void viewTaskExecs(final PropagationTaskTO taskTO, final AjaxRequestTarget target) {
mlp.next(
new StringResourceModel("task.view", this, new Model<>(Pair.of(null, taskTO))).getObject(),
- new TaskExecutionDetails<>(baseModal, taskTO, pageRef),
+ new TaskExecutionDetails<>(taskTO, pageRef),
target);
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/CommandComposeDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/CommandComposeDirectoryPanel.java
new file mode 100644
index 0000000000..82dc29bb3c
--- /dev/null
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/CommandComposeDirectoryPanel.java
@@ -0,0 +1,234 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.tasks;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.commons.IdRepoConstants;
+import org.apache.syncope.client.console.panels.DirectoryPanel;
+import org.apache.syncope.client.console.rest.CommandRestClient;
+import org.apache.syncope.client.console.rest.TaskRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
+import org.apache.syncope.client.ui.commons.Constants;
+import org.apache.syncope.client.ui.commons.DirectoryDataProvider;
+import org.apache.syncope.client.ui.commons.pages.BaseWebPage;
+import org.apache.syncope.client.ui.commons.panels.ModalPanel;
+import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.command.CommandTO;
+import org.apache.syncope.common.lib.to.MacroTaskTO;
+import org.apache.syncope.common.lib.types.IdRepoEntitlement;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
+import org.apache.wicket.event.Broadcast;
+import org.apache.wicket.event.IEvent;
+import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.ResourceModel;
+
+public class CommandComposeDirectoryPanel extends DirectoryPanel<
+ CommandWrapper, CommandWrapper, DirectoryDataProvider<CommandWrapper>, CommandRestClient>
+ implements ModalPanel {
+
+ private static final long serialVersionUID = 8899580817658145305L;
+
+ private final BaseModal<MacroTaskTO> baseModal;
+
+ private final String task;
+
+ public CommandComposeDirectoryPanel(
+ final BaseModal<MacroTaskTO> baseModal, final String task, final PageReference pageRef) {
+
+ super(BaseModal.CONTENT_ID, pageRef, false);
+
+ disableCheckBoxes();
+
+ this.baseModal = baseModal;
+ this.task = task;
+
+ enableUtilityButton();
+
+ addNewItemPanelBuilder(new CommandComposeWizardBuilder(task, new CommandWrapper(true), pageRef), true);
+
+ MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, RENDER, IdRepoEntitlement.TASK_UPDATE);
+ initResultTable();
+ }
+
+ @Override
+ protected List<IColumn<CommandWrapper, String>> getColumns() {
+ List<IColumn<CommandWrapper, String>> columns = new ArrayList<>();
+
+ columns.add(new AbstractColumn<>(new ResourceModel(Constants.KEY_FIELD_NAME), Constants.KEY_FIELD_NAME) {
+
+ private static final long serialVersionUID = -4008579357070833846L;
+
+ @Override
+ public void populateItem(
+ final Item<ICellPopulator<CommandWrapper>> cellItem,
+ final String componentId,
+ final IModel<CommandWrapper> rowModel) {
+
+ cellItem.add(new Label(componentId, rowModel.getObject().getCommand().getKey()));
+ }
+ });
+
+ columns.add(new AbstractColumn<>(new ResourceModel("arguments"), "arguments") {
+
+ private static final long serialVersionUID = -4008579357070833846L;
+
+ @Override
+ public void populateItem(
+ final Item<ICellPopulator<CommandWrapper>> cellItem,
+ final String componentId,
+ final IModel<CommandWrapper> rowModel) {
+
+ cellItem.add(new Label(componentId, rowModel.getObject().getCommand().getArgs().getClass().getName()));
+ }
+ });
+
+ return columns;
+ }
+
+ @Override
+ public ActionsPanel<CommandWrapper> getActions(final IModel<CommandWrapper> model) {
+ ActionsPanel<CommandWrapper> panel = super.getActions(model);
+
+ panel.add(new ActionLink<>() {
+
+ private static final long serialVersionUID = -3722207913631435501L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final CommandWrapper ignore) {
+ CommandComposeDirectoryPanel.this.getTogglePanel().close(target);
+ send(CommandComposeDirectoryPanel.this, Broadcast.EXACT,
+ new AjaxWizard.EditItemActionEvent<>(model.getObject(), target));
+ }
+ }, ActionLink.ActionType.EDIT, IdRepoEntitlement.TASK_UPDATE);
+
+ panel.add(new ActionLink<>() {
+
+ private static final long serialVersionUID = -3722207913631435501L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final CommandWrapper ignore) {
+ try {
+ MacroTaskTO actual = TaskRestClient.readTask(TaskType.MACRO, task);
+ actual.getCommands().remove(model.getObject().getCommand());
+ TaskRestClient.update(TaskType.MACRO, actual);
+
+ SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
+ customActionOnFinishCallback(target);
+ } catch (SyncopeClientException e) {
+ LOG.error("While deleting {}", model.getObject(), e);
+ SyncopeConsoleSession.get().onException(e);
+ }
+ ((BaseWebPage) pageRef.getPage()).getNotificationPanel().refresh(target);
+ }
+ }, ActionLink.ActionType.DELETE, IdRepoEntitlement.TASK_UPDATE);
+
+ return panel;
+ }
+
+ @Override
+ public ActionsPanel<Serializable> getHeader(final String componentId) {
+ ActionsPanel<Serializable> panel = new ActionsPanel<>(componentId, null);
+
+ panel.add(new ActionLink<>() {
+
+ private static final long serialVersionUID = -7978723352517770644L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
+ if (target != null) {
+ customActionOnFinishCallback(target);
+ }
+ }
+ }, ActionLink.ActionType.RELOAD, IdRepoEntitlement.TASK_READ).hideLabel();
+ return panel;
+ }
+
+ @Override
+ protected Collection<ActionLink.ActionType> getBatches() {
+ return List.of();
+ }
+
+ @Override
+ protected CommandComposeDataProvider dataProvider() {
+ return new CommandComposeDataProvider(rows);
+ }
+
+ @Override
+ protected String paginatorRowsKey() {
+ return IdRepoConstants.PREF_COMMAND_PAGINATOR_ROWS;
+ }
+
+ @Override
+ public void onEvent(final IEvent<?> event) {
+ super.onEvent(event);
+ if (event.getPayload() instanceof ExitEvent) {
+ AjaxRequestTarget target = ExitEvent.class.cast(event.getPayload()).getTarget();
+ baseModal.show(false);
+ baseModal.close(target);
+ }
+ }
+
+ protected class CommandComposeDataProvider extends DirectoryDataProvider<CommandWrapper> {
+
+ private static final long serialVersionUID = 4725679400450513556L;
+
+ public CommandComposeDataProvider(final int paginatorRows) {
+ super(paginatorRows);
+ }
+
+ @Override
+ public Iterator<CommandWrapper> iterator(final long first, final long count) {
+ MacroTaskTO actual = TaskRestClient.readTask(TaskType.MACRO, task);
+
+ List<CommandTO> commands = actual.getCommands();
+
+ return commands.subList((int) first, (int) (first + count)).stream().
+ map(command -> new CommandWrapper(false).setCommand(command)).
+ iterator();
+ }
+
+ @Override
+ public long size() {
+ MacroTaskTO actual = TaskRestClient.readTask(TaskType.MACRO, task);
+ return actual.getCommands().size();
+ }
+
+ @Override
+ public IModel<CommandWrapper> model(final CommandWrapper object) {
+ return new CompoundPropertyModel<>(object);
+ }
+ }
+}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/CommandComposeWizardBuilder.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/CommandComposeWizardBuilder.java
new file mode 100644
index 0000000000..93a24e40f9
--- /dev/null
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/CommandComposeWizardBuilder.java
@@ -0,0 +1,161 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.tasks;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.syncope.client.console.panels.BeanPanel;
+import org.apache.syncope.client.console.rest.CommandRestClient;
+import org.apache.syncope.client.console.rest.ImplementationRestClient;
+import org.apache.syncope.client.console.rest.TaskRestClient;
+import org.apache.syncope.client.console.wizards.BaseAjaxWizardBuilder;
+import org.apache.syncope.client.ui.commons.Constants;
+import org.apache.syncope.client.ui.commons.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior;
+import org.apache.syncope.common.lib.command.CommandTO;
+import org.apache.syncope.common.lib.to.ImplementationTO;
+import org.apache.syncope.common.lib.to.MacroTaskTO;
+import org.apache.syncope.common.lib.types.IdRepoImplementationType;
+import org.apache.syncope.common.lib.types.ImplementationEngine;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.extensions.ajax.markup.html.autocomplete.AutoCompleteSettings;
+import org.apache.wicket.extensions.ajax.markup.html.autocomplete.AutoCompleteTextField;
+import org.apache.wicket.extensions.wizard.WizardModel;
+import org.apache.wicket.extensions.wizard.WizardStep;
+import org.apache.wicket.model.LoadableDetachableModel;
+import org.apache.wicket.model.PropertyModel;
+
+public class CommandComposeWizardBuilder extends BaseAjaxWizardBuilder<CommandWrapper> {
+
+ private static final long serialVersionUID = -2300926041782845851L;
+
+ private final LoadableDetachableModel<List<ImplementationTO>> commands = new LoadableDetachableModel<>() {
+
+ private static final long serialVersionUID = 4659376149825914247L;
+
+ @Override
+ protected List<ImplementationTO> load() {
+ return ImplementationRestClient.list(IdRepoImplementationType.COMMAND);
+ }
+ };
+
+ private final String task;
+
+ public CommandComposeWizardBuilder(
+ final String task, final CommandWrapper defaultItem, final PageReference pageRef) {
+
+ super(defaultItem, pageRef);
+ this.task = task;
+ }
+
+ @Override
+ protected Serializable onApplyInternal(final CommandWrapper modelObject) {
+ MacroTaskTO taskTO = TaskRestClient.readTask(TaskType.MACRO, task);
+ if (modelObject.isNew()) {
+ taskTO.getCommands().add(modelObject.getCommand());
+ } else {
+ taskTO.getCommands().stream().
+ filter(cmd -> cmd.getKey().equals(modelObject.getCommand().getKey())).
+ findFirst().
+ ifPresent(cmd -> cmd.setArgs(modelObject.getCommand().getArgs()));
+ }
+
+ TaskRestClient.update(TaskType.MACRO, taskTO);
+ return modelObject;
+ }
+
+ @Override
+ protected WizardModel buildModelSteps(final CommandWrapper modelObject, final WizardModel wizardModel) {
+ wizardModel.add(new Profile(modelObject));
+ wizardModel.add(new CommandArgs(modelObject));
+ return wizardModel;
+ }
+
+ public class Profile extends WizardStep {
+
+ private static final long serialVersionUID = -3043839139187792810L;
+
+ private final CommandWrapper command;
+
+ public Profile(final CommandWrapper command) {
+ this.command = command;
+ MacroTaskTO taskTO = TaskRestClient.readTask(TaskType.MACRO, task);
+
+ AutoCompleteSettings settings = new AutoCompleteSettings();
+ settings.setShowCompleteListOnFocusGain(false);
+ settings.setShowListOnEmptyInput(false);
+
+ AutoCompleteTextField<String> args = new AutoCompleteTextField<>(
+ "command", new PropertyModel<>(command, "command.key"), settings) {
+
+ private static final long serialVersionUID = -6556576139048844857L;
+
+ @Override
+ protected Iterator<String> getChoices(final String input) {
+ return commands.getObject().stream().
+ map(ImplementationTO::getKey).
+ filter(cmd -> cmd.contains(input)
+ && taskTO.getCommands().stream().noneMatch(c -> c.getKey().equals(cmd))).
+ sorted().iterator();
+ }
+ };
+ args.setRequired(true);
+ args.setEnabled(command.isNew());
+ args.add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+ private static final long serialVersionUID = -6139318907146065915L;
+
+ @Override
+ protected void onUpdate(final AjaxRequestTarget target) {
+ CommandTO cmd = CommandRestClient.read(command.getCommand().getKey());
+ command.getCommand().setArgs(cmd.getArgs());
+ }
+ });
+ add(args);
+ }
+
+ @Override
+ public void applyState() {
+ commands.getObject().stream().
+ filter(cmd -> cmd.getKey().equals(command.getCommand().getKey())
+ && cmd.getEngine() == ImplementationEngine.GROOVY).
+ findFirst().ifPresent(cmd -> getWizardModel().finish());
+ }
+ }
+
+ public class CommandArgs extends WizardStep {
+
+ private static final long serialVersionUID = -785981096328637758L;
+
+ public CommandArgs(final CommandWrapper command) {
+ LoadableDetachableModel<Serializable> bean = new LoadableDetachableModel<>() {
+
+ private static final long serialVersionUID = 2092144708018739371L;
+
+ @Override
+ protected Serializable load() {
+ return command.getCommand().getArgs();
+ }
+ };
+ add(new BeanPanel<>("bean", bean, pageRef).setRenderBodyOnly(true));
+ }
+ }
+}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/ExecMessage.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/CommandWrapper.java
similarity index 54%
copy from client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/ExecMessage.java
copy to client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/CommandWrapper.java
index 293e051987..d8dab2d5c6 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/ExecMessage.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/CommandWrapper.java
@@ -18,16 +18,36 @@
*/
package org.apache.syncope.client.console.tasks;
-import org.apache.syncope.client.console.panels.MultilevelPanel;
-import org.apache.wicket.markup.html.basic.Label;
-import org.apache.wicket.model.Model;
+import java.io.Serializable;
+import org.apache.syncope.common.lib.command.CommandTO;
-public class ExecMessage extends MultilevelPanel.SecondLevel {
+public class CommandWrapper implements Serializable {
- private static final long serialVersionUID = 3163146190501510888L;
+ private static final long serialVersionUID = -2423427579112218652L;
- public ExecMessage(final String message) {
- super();
- add(new Label("message", Model.of(message)).setOutputMarkupId(true));
+ private final boolean isNew;
+
+ private CommandTO command;
+
+ public CommandWrapper(final boolean isNew) {
+ this.isNew = isNew;
+ }
+
+ public boolean isNew() {
+ return isNew;
+ }
+
+ public CommandTO getCommand() {
+ return command;
+ }
+
+ public CommandWrapper setCommand(final CommandTO command) {
+ this.command = command;
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return "CommandWrapper{" + "isNew=" + isNew + ", command=" + command + '}';
}
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/ExecMessage.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/ExecMessage.java
index 293e051987..f09179d056 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/ExecMessage.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/ExecMessage.java
@@ -28,6 +28,15 @@ public class ExecMessage extends MultilevelPanel.SecondLevel {
public ExecMessage(final String message) {
super();
+ init(message);
+ }
+
+ public ExecMessage(final String id, final String message) {
+ super(id);
+ init(message);
+ }
+
+ protected void init(final String message) {
add(new Label("message", Model.of(message)).setOutputMarkupId(true));
}
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.java
index a4873d15a3..658eabcddc 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.java
@@ -33,7 +33,6 @@ import org.apache.syncope.client.console.rest.ExecutionRestClient;
import org.apache.syncope.client.console.tasks.ExecutionsDirectoryPanel.ExecProvider;
import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.DatePropertyColumn;
import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.KeyPropertyColumn;
-import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
import org.apache.syncope.client.ui.commons.Constants;
@@ -54,29 +53,18 @@ public abstract class ExecutionsDirectoryPanel
private static final long serialVersionUID = 2039393934721149162L;
- private final BaseModal<?> baseModal;
+ protected final MultilevelPanel multiLevelPanelRef;
- private final MultilevelPanel multiLevelPanelRef;
-
- private final String key;
+ protected final String key;
public ExecutionsDirectoryPanel(
final MultilevelPanel multiLevelPanelRef,
final String key,
final ExecutionRestClient executionRestClient,
final PageReference pageRef) {
- this(null, multiLevelPanelRef, key, executionRestClient, pageRef);
- }
- public ExecutionsDirectoryPanel(
- final BaseModal<?> baseModal,
- final MultilevelPanel multiLevelPanelRef,
- final String key,
- final ExecutionRestClient executionRestClient,
- final PageReference pageRef) {
super(MultilevelPanel.FIRST_LEVEL_ID, pageRef, false);
- this.baseModal = baseModal;
this.multiLevelPanelRef = multiLevelPanelRef;
restClient = executionRestClient;
setOutputMarkupId(true);
@@ -86,14 +74,14 @@ public abstract class ExecutionsDirectoryPanel
@Override
protected void resultTableCustomChanges(final AjaxDataTablePanel.Builder<ExecTO, String> resultTableBuilder) {
- resultTableBuilder.setMultiLevelPanel(baseModal, multiLevelPanelRef);
+ resultTableBuilder.setMultiLevelPanel(multiLevelPanelRef);
}
protected abstract void next(String title, SecondLevel secondLevel, AjaxRequestTarget target);
@Override
protected List<IColumn<ExecTO, String>> getColumns() {
- final List<IColumn<ExecTO, String>> columns = new ArrayList<>();
+ List<IColumn<ExecTO, String>> columns = new ArrayList<>();
columns.add(new KeyPropertyColumn<>(
new StringResourceModel(Constants.KEY_FIELD_NAME, this),
@@ -112,8 +100,7 @@ public abstract class ExecutionsDirectoryPanel
@Override
public ActionsPanel<ExecTO> getActions(final IModel<ExecTO> model) {
- final ActionsPanel<ExecTO> panel = super.getActions(model);
- final ExecTO taskExecutionTO = model.getObject();
+ ActionsPanel<ExecTO> panel = super.getActions(model);
panel.add(new ActionLink<>() {
@@ -123,9 +110,10 @@ public abstract class ExecutionsDirectoryPanel
public void onClick(final AjaxRequestTarget target, final ExecTO ignore) {
ExecutionsDirectoryPanel.this.getTogglePanel().close(target);
next(new StringResourceModel("execution.view", ExecutionsDirectoryPanel.this, model).
- getObject(), new ExecMessage(model.getObject().getMessage()), target);
+ getObject(), new ExecMessage(model.getObject().getMessage()), target);
}
}, ActionLink.ActionType.VIEW, IdRepoEntitlement.TASK_READ);
+
panel.add(new ActionLink<>() {
private static final long serialVersionUID = -3722207913631435501L;
@@ -134,7 +122,7 @@ public abstract class ExecutionsDirectoryPanel
public void onClick(final AjaxRequestTarget target, final ExecTO ignore) {
ExecutionsDirectoryPanel.this.getTogglePanel().close(target);
try {
- restClient.deleteExecution(taskExecutionTO.getKey());
+ restClient.deleteExecution(model.getObject().getKey());
SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
target.add(container);
} catch (SyncopeClientException e) {
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/MacroTaskDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/MacroTaskDirectoryPanel.java
new file mode 100644
index 0000000000..92d2e094cc
--- /dev/null
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/MacroTaskDirectoryPanel.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.tasks;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.client.console.panels.MultilevelPanel;
+import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.BooleanPropertyColumn;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
+import org.apache.syncope.common.lib.to.MacroTaskTO;
+import org.apache.syncope.common.lib.types.IdRepoEntitlement;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.model.StringResourceModel;
+
+public class MacroTaskDirectoryPanel extends SchedTaskDirectoryPanel<MacroTaskTO> {
+
+ private static final long serialVersionUID = -6247673131495530094L;
+
+ public MacroTaskDirectoryPanel(final MultilevelPanel mlp, final PageReference pageRef) {
+ super(MultilevelPanel.FIRST_LEVEL_ID, null, mlp, TaskType.MACRO, new MacroTaskTO(), pageRef, true);
+ }
+
+ @Override
+ protected List<IColumn<MacroTaskTO, String>> getFieldColumns() {
+ List<IColumn<MacroTaskTO, String>> columns = new ArrayList<>();
+
+ columns.addAll(getHeadingFieldColumns());
+
+ columns.add(new BooleanPropertyColumn<>(
+ new ResourceModel("continueOnError"), "continueOnError", "continueOnError"));
+ columns.add(new BooleanPropertyColumn<>(
+ new ResourceModel("saveExecs"), "saveExecs", "saveExecs"));
+
+ columns.addAll(getTrailingFieldColumns());
+
+ return columns;
+ }
+
+ @Override
+ protected void viewTaskExecs(final MacroTaskTO taskTO, final AjaxRequestTarget target) {
+ multiLevelPanelRef.next(
+ new StringResourceModel("task.view", this, new Model<>(Pair.of(null, taskTO))).getObject(),
+ new TaskExecutionDetails<>(taskTO, pageRef),
+ target);
+ }
+
+ @Override
+ protected void addFurtherActions(final ActionsPanel<MacroTaskTO> panel, final IModel<MacroTaskTO> model) {
+ panel.add(new ActionLink<>() {
+
+ private static final long serialVersionUID = -3722207913631435501L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final MacroTaskTO ignore) {
+ target.add(modal.setContent(
+ new CommandComposeDirectoryPanel(modal, model.getObject().getKey(), pageRef)));
+
+ modal.header(new StringResourceModel(
+ "command.conf", MacroTaskDirectoryPanel.this, Model.of(model.getObject())));
+ modal.show(true);
+ }
+ }, ActionLink.ActionType.COMPOSE, IdRepoEntitlement.TASK_UPDATE);
+ }
+}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/NotificationTaskDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/NotificationTaskDirectoryPanel.java
index 32506d3839..5e2da31309 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/NotificationTaskDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/NotificationTaskDirectoryPanel.java
@@ -67,7 +67,7 @@ public abstract class NotificationTaskDirectoryPanel
final MultilevelPanel multiLevelPanelRef,
final PageReference pageRef) {
- super(null, multiLevelPanelRef, pageRef);
+ super(null, multiLevelPanelRef, pageRef, false);
this.notification = notification;
this.anyTypeKind = anyTypeKind;
this.entityKey = entityKey;
@@ -78,7 +78,7 @@ public abstract class NotificationTaskDirectoryPanel
@Override
protected List<IColumn<NotificationTaskTO, String>> getColumns() {
- final List<IColumn<NotificationTaskTO, String>> columns = new ArrayList<>();
+ List<IColumn<NotificationTaskTO, String>> columns = new ArrayList<>();
columns.add(new KeyPropertyColumn<>(
new StringResourceModel(Constants.KEY_FIELD_NAME, this), Constants.KEY_FIELD_NAME));
@@ -100,6 +100,7 @@ public abstract class NotificationTaskDirectoryPanel
columns.add(new PropertyColumn<>(
new StringResourceModel("latestExecStatus", this), "latestExecStatus", "latestExecStatus"));
+
return columns;
}
@@ -114,7 +115,7 @@ public abstract class NotificationTaskDirectoryPanel
@Override
public void onClick(final AjaxRequestTarget target, final NotificationTaskTO modelObject) {
- viewTask(taskTO, target);
+ viewTaskExecs(taskTO, target);
}
}, ActionLink.ActionType.VIEW, IdRepoEntitlement.TASK_READ);
panel.add(new ActionLink<>() {
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/PropagationTaskDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/PropagationTaskDirectoryPanel.java
index 7d398f1d68..579903b1d3 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/PropagationTaskDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/PropagationTaskDirectoryPanel.java
@@ -61,14 +61,15 @@ public abstract class PropagationTaskDirectoryPanel
final MultilevelPanel multiLevelPanelRef,
final String resource,
final PageReference pageRef) {
- super(baseModal, multiLevelPanelRef, pageRef);
+
+ super(baseModal, multiLevelPanelRef, pageRef, false);
this.resource = resource;
initResultTable();
}
@Override
protected List<IColumn<PropagationTaskTO, String>> getColumns() {
- final List<IColumn<PropagationTaskTO, String>> columns = new ArrayList<>();
+ List<IColumn<PropagationTaskTO, String>> columns = new ArrayList<>();
columns.add(new KeyPropertyColumn<>(
new StringResourceModel(Constants.KEY_FIELD_NAME, this), Constants.KEY_FIELD_NAME));
@@ -81,7 +82,7 @@ public abstract class PropagationTaskDirectoryPanel
new StringResourceModel("resource", this), "resource", "resource"));
} else {
columns.add(new PropertyColumn<>(
- new StringResourceModel("anyTypeKind", this), "anyTypeKind", "anyTypeKind") {
+ new StringResourceModel("anyTypeKind", this), "anyTypeKind", "anyTypeKind") {
private static final long serialVersionUID = 3344577098912281394L;
@@ -110,6 +111,7 @@ public abstract class PropagationTaskDirectoryPanel
columns.add(new PropertyColumn<>(
new StringResourceModel("latestExecStatus", this), "latestExecStatus", "latestExecStatus"));
+
return columns;
}
@@ -125,7 +127,7 @@ public abstract class PropagationTaskDirectoryPanel
@Override
public void onClick(final AjaxRequestTarget target, final PropagationTaskTO modelObject) {
PropagationTaskDirectoryPanel.this.getTogglePanel().close(target);
- viewTask(taskTO, target);
+ viewTaskExecs(taskTO, target);
}
}, ActionLink.ActionType.VIEW_EXECUTIONS, IdRepoEntitlement.TASK_READ);
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/PropagationTasks.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/PropagationTasks.java
index b6d7b9f430..b4beae3674 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/PropagationTasks.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/PropagationTasks.java
@@ -39,29 +39,29 @@ public class PropagationTasks extends AbstractPropagationTasks {
super(BaseModal.CONTENT_ID);
- final MultilevelPanel tasks = new MultilevelPanel("tasks");
-
- tasks.setFirstLevel(new PropagationTaskDirectoryPanel(baseModal, tasks, resource, pageRef) {
+ MultilevelPanel mlp = new MultilevelPanel("tasks");
+ add(mlp);
+
+ mlp.setFirstLevel(new PropagationTaskDirectoryPanel(baseModal, mlp, resource, pageRef) {
private static final long serialVersionUID = -2195387360323687302L;
@Override
- protected void viewTask(final PropagationTaskTO taskTO, final AjaxRequestTarget target) {
- tasks.next(
+ protected void viewTaskExecs(final PropagationTaskTO taskTO, final AjaxRequestTarget target) {
+ mlp.next(
new StringResourceModel("task.view", this, new Model<>(Pair.of(null, taskTO))).getObject(),
- new TaskExecutionDetails<>(baseModal, taskTO, pageRef),
+ new TaskExecutionDetails<>(taskTO, pageRef),
target);
}
@Override
protected void viewTaskDetails(final PropagationTaskTO taskTO, final AjaxRequestTarget target) {
- tasks.next(
- new StringResourceModel("task.view.details", this, new Model<>(Pair.of(null, taskTO))).
- getObject(),
+ mlp.next(
+ new StringResourceModel(
+ "task.view.details", this, new Model<>(Pair.of(null, taskTO))).getObject(),
new PropagationDataView(taskTO),
target);
}
});
- add(tasks);
}
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/ProvisioningTaskDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/ProvisioningTaskDirectoryPanel.java
index 2fd8dc16f4..33efcc8f46 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/ProvisioningTaskDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/ProvisioningTaskDirectoryPanel.java
@@ -25,32 +25,17 @@ import java.util.List;
import org.apache.syncope.client.console.panels.MultilevelPanel;
import org.apache.syncope.client.console.rest.TaskRestClient;
import org.apache.syncope.client.console.wicket.ajax.IndicatorAjaxTimerBehavior;
-import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.BooleanPropertyColumn;
-import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.DatePropertyColumn;
-import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.KeyPropertyColumn;
import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
import org.apache.syncope.client.console.widgets.JobActionPanel;
-import org.apache.syncope.client.ui.commons.Constants;
-import org.apache.syncope.common.lib.to.JobTO;
import org.apache.syncope.common.lib.to.ProvisioningTaskTO;
import org.apache.syncope.common.lib.to.PullTaskTO;
import org.apache.syncope.common.lib.to.PushTaskTO;
-import org.apache.syncope.common.lib.types.IdRepoEntitlement;
import org.apache.syncope.common.lib.types.TaskType;
-import org.apache.wicket.Component;
import org.apache.wicket.PageReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
import org.apache.wicket.event.IEvent;
-import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
-import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
-import org.apache.wicket.markup.html.WebPage;
-import org.apache.wicket.markup.html.basic.Label;
-import org.apache.wicket.markup.repeater.Item;
-import org.apache.wicket.model.IModel;
-import org.apache.wicket.model.Model;
import org.apache.wicket.model.StringResourceModel;
/**
@@ -69,16 +54,17 @@ public abstract class ProvisioningTaskDirectoryPanel<T extends ProvisioningTaskT
final BaseModal<?> baseModal,
final MultilevelPanel multiLevelPanelRef,
final TaskType taskType,
- final Class<T> reference,
+ final T newTaskTO,
final String resource,
final PageReference pageRef) {
- super(baseModal, multiLevelPanelRef, taskType, reference, pageRef);
+ super(MultilevelPanel.FIRST_LEVEL_ID, baseModal, multiLevelPanelRef, taskType, newTaskTO, pageRef, false);
this.resource = resource;
this.schedTaskTO.setResource(resource);
// super in order to call the parent implementation
+ enableUtilityButton();
super.initResultTable();
container.add(new IndicatorAjaxTimerBehavior(java.time.Duration.of(10, ChronoUnit.SECONDS)) {
@@ -102,66 +88,17 @@ public abstract class ProvisioningTaskDirectoryPanel<T extends ProvisioningTaskT
protected List<IColumn<T, String>> getFieldColumns() {
List<IColumn<T, String>> columns = new ArrayList<>();
- columns.add(new KeyPropertyColumn<>(
- new StringResourceModel(Constants.KEY_FIELD_NAME, this), Constants.KEY_FIELD_NAME));
+ columns.addAll(getHeadingFieldColumns());
- columns.add(new PropertyColumn<>(
- new StringResourceModel(Constants.NAME_FIELD_NAME, this),
- Constants.NAME_FIELD_NAME, Constants.NAME_FIELD_NAME));
-
- columns.add(new PropertyColumn<>(
- new StringResourceModel(Constants.DESCRIPTION_FIELD_NAME, this),
- Constants.DESCRIPTION_FIELD_NAME, Constants.DESCRIPTION_FIELD_NAME));
-
- if (reference == PullTaskTO.class) {
+ if (schedTaskTO instanceof PullTaskTO) {
columns.add(new PropertyColumn<>(
new StringResourceModel("destinationRealm", this), "destinationRealm", "destinationRealm"));
- } else if (reference == PushTaskTO.class) {
+ } else if (schedTaskTO instanceof PushTaskTO) {
columns.add(new PropertyColumn<>(
new StringResourceModel("sourceRealm", this), "sourceRealm", "sourceRealm"));
}
- columns.add(new DatePropertyColumn<>(
- new StringResourceModel("lastExec", this), null, "lastExec"));
-
- columns.add(new DatePropertyColumn<>(
- new StringResourceModel("nextExec", this), null, "nextExec"));
-
- columns.add(new PropertyColumn<>(
- new StringResourceModel("latestExecStatus", this), "latestExecStatus", "latestExecStatus"));
-
- columns.add(new BooleanPropertyColumn<>(
- new StringResourceModel("active", this), "active", "active"));
-
- columns.add(new AbstractColumn<>(new Model<>(""), "running") {
-
- private static final long serialVersionUID = -4008579357070833846L;
-
- @Override
- public void populateItem(
- final Item<ICellPopulator<T>> cellItem,
- final String componentId,
- final IModel<T> rowModel) {
-
- Component panel;
- try {
- JobTO jobTO = TaskRestClient.getJob(rowModel.getObject().getKey());
- panel = new JobActionPanel(componentId, jobTO, false, ProvisioningTaskDirectoryPanel.this);
- MetaDataRoleAuthorizationStrategy.authorize(
- panel, WebPage.ENABLE,
- String.format("%s,%s", IdRepoEntitlement.TASK_EXECUTE, IdRepoEntitlement.TASK_UPDATE));
- } catch (Exception e) {
- LOG.error("Could not get job for task {}", rowModel.getObject().getKey(), e);
- panel = new Label(componentId, Model.of());
- }
- cellItem.add(panel);
- }
-
- @Override
- public String getCssClass() {
- return "col-xs-1";
- }
- });
+ columns.addAll(getTrailingFieldColumns());
return columns;
}
@@ -180,11 +117,8 @@ public abstract class ProvisioningTaskDirectoryPanel<T extends ProvisioningTaskT
private static final long serialVersionUID = 4725679400450513556L;
- private final Class<T> reference;
-
- public ProvisioningTasksProvider(final Class<T> reference, final TaskType id, final int paginatorRows) {
- super(reference, id, paginatorRows);
- this.reference = reference;
+ public ProvisioningTasksProvider(final TaskType taskType, final int paginatorRows) {
+ super(taskType, paginatorRows);
}
@Override
@@ -195,8 +129,8 @@ public abstract class ProvisioningTaskDirectoryPanel<T extends ProvisioningTaskT
@Override
public Iterator<T> iterator(final long first, final long count) {
int page = ((int) first / paginatorRows);
- return TaskRestClient.list(
- resource, reference, (page < 0 ? 0 : page) + 1, paginatorRows, getSort()).
+ return TaskRestClient.<T>list(
+ resource, taskType, (page < 0 ? 0 : page) + 1, paginatorRows, getSort()).
iterator();
}
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/PullTaskDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/PullTaskDirectoryPanel.java
index b496930640..b61580c222 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/PullTaskDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/PullTaskDirectoryPanel.java
@@ -40,7 +40,7 @@ public abstract class PullTaskDirectoryPanel extends ProvisioningTaskDirectoryPa
final String resource,
final PageReference pageRef) {
- super(baseModal, multiLevelPanelRef, TaskType.PULL, PullTaskTO.class, resource, pageRef);
+ super(baseModal, multiLevelPanelRef, TaskType.PULL, new PullTaskTO(), resource, pageRef);
}
@Override
@@ -50,7 +50,7 @@ public abstract class PullTaskDirectoryPanel extends ProvisioningTaskDirectoryPa
@Override
protected ProvisioningTasksProvider<PullTaskTO> dataProvider() {
- return new ProvisioningTasksProvider<>(reference, TaskType.PULL, rows);
+ return new ProvisioningTasksProvider<>(TaskType.PULL, rows);
}
@Override
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/PullTasks.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/PullTasks.java
index ca8bf343a8..6faf4181ca 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/PullTasks.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/PullTasks.java
@@ -33,10 +33,11 @@ public class PullTasks extends AbstractTasks {
private static final long serialVersionUID = -4013796607157549641L;
public <T extends AnyTO> PullTasks(
- final BaseModal<?> baseModal, final PageReference pageRef, final String resource) {
+ final BaseModal<?> baseModal, final String resource, final PageReference pageRef) {
+
super(BaseModal.CONTENT_ID);
- final MultilevelPanel mlp = new MultilevelPanel("tasks");
+ MultilevelPanel mlp = new MultilevelPanel("tasks");
add(mlp);
mlp.setFirstLevel(new PullTaskDirectoryPanel(baseModal, mlp, resource, pageRef) {
@@ -44,10 +45,11 @@ public class PullTasks extends AbstractTasks {
private static final long serialVersionUID = -2195387360323687302L;
@Override
- protected void viewTask(final PullTaskTO taskTO, final AjaxRequestTarget target) {
+ protected void viewTaskExecs(final PullTaskTO taskTO, final AjaxRequestTarget target) {
mlp.next(
new StringResourceModel("task.view", this, new Model<>(Pair.of(null, taskTO))).getObject(),
- new TaskExecutionDetails<>(baseModal, taskTO, pageRef), target);
+ new TaskExecutionDetails<>(taskTO, pageRef),
+ target);
}
});
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/PushTaskDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/PushTaskDirectoryPanel.java
index 94c5e23b85..0a6eab078e 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/PushTaskDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/PushTaskDirectoryPanel.java
@@ -37,7 +37,7 @@ public abstract class PushTaskDirectoryPanel extends ProvisioningTaskDirectoryPa
final MultilevelPanel multiLevelPanelRef,
final String resource,
final PageReference pageRef) {
- super(baseModal, multiLevelPanelRef, TaskType.PUSH, PushTaskTO.class, resource, pageRef);
+ super(baseModal, multiLevelPanelRef, TaskType.PUSH, new PushTaskTO(), resource, pageRef);
}
@Override
@@ -47,6 +47,6 @@ public abstract class PushTaskDirectoryPanel extends ProvisioningTaskDirectoryPa
@Override
protected ProvisioningTasksProvider<PushTaskTO> dataProvider() {
- return new ProvisioningTasksProvider<>(reference, TaskType.PUSH, rows);
+ return new ProvisioningTasksProvider<>(TaskType.PUSH, rows);
}
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/PushTasks.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/PushTasks.java
index 56dea3a05c..47828c52ed 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/PushTasks.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/PushTasks.java
@@ -33,21 +33,23 @@ public class PushTasks extends AbstractTasks {
private static final long serialVersionUID = -4013796607157549641L;
public <T extends AnyTO> PushTasks(
- final BaseModal<?> baseModal, final PageReference pageReference, final String resource) {
+ final BaseModal<?> baseModal, final String resource, final PageReference pageRef) {
+
super(BaseModal.CONTENT_ID);
- final MultilevelPanel mlp = new MultilevelPanel("tasks");
+ MultilevelPanel mlp = new MultilevelPanel("tasks");
add(mlp);
- mlp.setFirstLevel(new PushTaskDirectoryPanel(baseModal, mlp, resource, pageReference) {
+ mlp.setFirstLevel(new PushTaskDirectoryPanel(baseModal, mlp, resource, pageRef) {
private static final long serialVersionUID = -2195387360323687302L;
@Override
- protected void viewTask(final PushTaskTO taskTO, final AjaxRequestTarget target) {
+ protected void viewTaskExecs(final PushTaskTO taskTO, final AjaxRequestTarget target) {
mlp.next(
new StringResourceModel("task.view", this, new Model<>(Pair.of(null, taskTO))).getObject(),
- new TaskExecutionDetails<>(baseModal, taskTO, pageReference), target);
+ new TaskExecutionDetails<>(taskTO, pageRef),
+ target);
}
});
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.java
index 3aa524bf1f..7a0e48abba 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.java
@@ -18,6 +18,7 @@
*/
package org.apache.syncope.client.console.tasks;
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
import java.io.Serializable;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
@@ -79,95 +80,33 @@ public abstract class SchedTaskDirectoryPanel<T extends SchedTaskTO>
private static final long serialVersionUID = 4984337552918213290L;
- protected TaskType taskType;
+ protected final TaskType taskType;
- protected final Class<T> reference;
+ protected final T schedTaskTO;
- protected T schedTaskTO;
-
- private final TaskStartAtTogglePanel startAt;
+ protected final TaskStartAtTogglePanel startAt;
protected final TemplatesTogglePanel templates;
protected SchedTaskDirectoryPanel(
+ final String id,
final BaseModal<?> baseModal,
final MultilevelPanel multiLevelPanelRef,
final TaskType taskType,
- final Class<T> reference,
- final PageReference pageRef) {
-
- super(baseModal, multiLevelPanelRef, pageRef);
- this.taskType = taskType;
- this.reference = reference;
-
- try {
- schedTaskTO = reference.getDeclaredConstructor().newInstance();
- } catch (Exception e) {
- LOG.error("Failure instantiating task", e);
- }
-
- this.addNewItemPanelBuilder(new SchedTaskWizardBuilder<>(taskType, schedTaskTO, pageRef), true);
-
- MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, RENDER, IdRepoEntitlement.TASK_CREATE);
-
- enableUtilityButton();
- setFooterVisibility(false);
-
- initResultTable();
-
- container.add(new IndicatorAjaxTimerBehavior(Duration.of(10, ChronoUnit.SECONDS)) {
-
- private static final long serialVersionUID = -4661303265651934868L;
-
- @Override
- protected void onTimer(final AjaxRequestTarget target) {
- container.modelChanged();
- target.add(container);
- }
- });
-
- startAt = new TaskStartAtTogglePanel(container, pageRef);
- addInnerObject(startAt);
-
- templates = new TemplatesTogglePanel(getActualId(), this, pageRef) {
-
- private static final long serialVersionUID = -8765794727538618705L;
-
- @Override
- protected Serializable onApplyInternal(
- final TemplatableTO targetObject, final String type, final AnyTO anyTO) {
-
- targetObject.getTemplates().put(type, anyTO);
- TaskRestClient.update(taskType, SchedTaskTO.class.cast(targetObject));
- return targetObject;
- }
- };
- addInnerObject(templates);
- }
-
- protected SchedTaskDirectoryPanel(
- final BaseModal<?> baseModal,
- final MultilevelPanel multiLevelPanelRef,
- final TaskType taskType,
- final Class<T> reference,
+ final T newTaskTO,
final PageReference pageRef,
final boolean wizardInModal) {
- super(baseModal, multiLevelPanelRef, pageRef, wizardInModal);
+ super(id, baseModal, multiLevelPanelRef, pageRef, wizardInModal);
this.taskType = taskType;
- this.reference = reference;
+ this.schedTaskTO = newTaskTO;
- try {
- schedTaskTO = reference.getDeclaredConstructor().newInstance();
- } catch (Exception e) {
- LOG.error("Failure instantiating task", e);
- }
+ modal.size(Modal.Size.Large);
- this.addNewItemPanelBuilder(new SchedTaskWizardBuilder<>(taskType, schedTaskTO, pageRef), true);
+ addNewItemPanelBuilder(new SchedTaskWizardBuilder<>(taskType, schedTaskTO, pageRef), true);
MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, RENDER, IdRepoEntitlement.TASK_CREATE);
- enableUtilityButton();
setFooterVisibility(false);
initResultTable();
@@ -202,7 +141,7 @@ public abstract class SchedTaskDirectoryPanel<T extends SchedTaskTO>
addInnerObject(templates);
}
- protected List<IColumn<T, String>> getFieldColumns() {
+ protected List<IColumn<T, String>> getHeadingFieldColumns() {
List<IColumn<T, String>> columns = new ArrayList<>();
columns.add(new KeyPropertyColumn<>(
@@ -212,30 +151,11 @@ public abstract class SchedTaskDirectoryPanel<T extends SchedTaskTO>
new StringResourceModel(Constants.NAME_FIELD_NAME, this),
Constants.NAME_FIELD_NAME, Constants.NAME_FIELD_NAME));
- columns.add(new PropertyColumn<>(
- new StringResourceModel("jobDelegate", this), "jobDelegate", "jobDelegate") {
-
- private static final long serialVersionUID = -3223917055078733093L;
-
- @Override
- public void populateItem(
- final Item<ICellPopulator<T>> item,
- final String componentId,
- final IModel<T> rowModel) {
+ return columns;
+ }
- IModel<?> model = getDataModel(rowModel);
- if (model != null && model.getObject() instanceof String) {
- String value = String.class.cast(model.getObject());
- if (value.length() > 20) {
- item.add(new Label(componentId, new Model<>("..." + value.substring(value.length() - 17))));
- } else {
- item.add(new Label(componentId, getDataModel(rowModel)));
- }
- } else {
- super.populateItem(item, componentId, rowModel);
- }
- }
- });
+ protected List<IColumn<T, String>> getTrailingFieldColumns() {
+ List<IColumn<T, String>> columns = new ArrayList<>();
columns.add(new DatePropertyColumn<>(
new StringResourceModel("lastExec", this), null, "lastExec"));
@@ -255,17 +175,17 @@ public abstract class SchedTaskDirectoryPanel<T extends SchedTaskTO>
@Override
public void populateItem(
- final Item<ICellPopulator<T>> cellItem,
- final String componentId,
- final IModel<T> rowModel) {
+ final Item<ICellPopulator<T>> cellItem,
+ final String componentId,
+ final IModel<T> rowModel) {
Component panel;
try {
JobTO jobTO = TaskRestClient.getJob(rowModel.getObject().getKey());
panel = new JobActionPanel(componentId, jobTO, false, SchedTaskDirectoryPanel.this);
MetaDataRoleAuthorizationStrategy.authorize(
- panel, WebPage.ENABLE,
- String.format("%s,%s", IdRepoEntitlement.TASK_EXECUTE, IdRepoEntitlement.TASK_UPDATE));
+ panel, WebPage.ENABLE,
+ String.format("%s,%s", IdRepoEntitlement.TASK_EXECUTE, IdRepoEntitlement.TASK_UPDATE));
} catch (Exception e) {
LOG.error("Could not get job for task {}", rowModel.getObject().getKey(), e);
panel = new Label(componentId, Model.of());
@@ -275,25 +195,60 @@ public abstract class SchedTaskDirectoryPanel<T extends SchedTaskTO>
@Override
public String getCssClass() {
- return "col-xs-1";
+ return "running-col";
}
});
return columns;
}
+ protected List<IColumn<T, String>> getFieldColumns() {
+ List<IColumn<T, String>> columns = new ArrayList<>();
+
+ columns.addAll(getHeadingFieldColumns());
+
+ columns.add(new PropertyColumn<>(new StringResourceModel("jobDelegate", this), "jobDelegate", "jobDelegate") {
+
+ private static final long serialVersionUID = -3223917055078733093L;
+
+ @Override
+ public void populateItem(
+ final Item<ICellPopulator<T>> item,
+ final String componentId,
+ final IModel<T> rowModel) {
+
+ IModel<?> model = getDataModel(rowModel);
+ if (model != null && model.getObject() instanceof String) {
+ String value = String.class.cast(model.getObject());
+ if (value.length() > 20) {
+ item.add(new Label(componentId, new Model<>("..." + value.substring(value.length() - 17))));
+ } else {
+ item.add(new Label(componentId, getDataModel(rowModel)));
+ }
+ } else {
+ super.populateItem(item, componentId, rowModel);
+ }
+ }
+ });
+
+ columns.addAll(getTrailingFieldColumns());
+
+ return columns;
+ }
+
@Override
protected final List<IColumn<T, String>> getColumns() {
- final List<IColumn<T, String>> columns = new ArrayList<>();
+ List<IColumn<T, String>> columns = new ArrayList<>();
columns.addAll(getFieldColumns());
+
return columns;
}
@Override
public ActionsPanel<T> getActions(final IModel<T> model) {
- final ActionsPanel<T> panel = super.getActions(model);
- final T taskTO = model.getObject();
+ ActionsPanel<T> panel = super.getActions(model);
+ T taskTO = model.getObject();
panel.add(new ActionLink<>() {
@@ -302,7 +257,7 @@ public abstract class SchedTaskDirectoryPanel<T extends SchedTaskTO>
@Override
public void onClick(final AjaxRequestTarget target, final T ignore) {
SchedTaskDirectoryPanel.this.getTogglePanel().close(target);
- viewTask(taskTO, target);
+ viewTaskExecs(taskTO, target);
}
}, ActionLink.ActionType.VIEW_EXECUTIONS, IdRepoEntitlement.TASK_READ);
@@ -314,12 +269,12 @@ public abstract class SchedTaskDirectoryPanel<T extends SchedTaskTO>
public void onClick(final AjaxRequestTarget target, final T ignore) {
SchedTaskDirectoryPanel.this.getTogglePanel().close(target);
send(SchedTaskDirectoryPanel.this, Broadcast.EXACT,
- new AjaxWizard.EditItemActionEvent<>(
- TaskRestClient.readTask(taskType, model.getObject().getKey()),
- target).setResourceModel(
- new StringResourceModel("inner.task.edit",
- SchedTaskDirectoryPanel.this,
- Model.of(Pair.of(ActionLink.ActionType.EDIT, model.getObject())))));
+ new AjaxWizard.EditItemActionEvent<>(
+ TaskRestClient.readTask(taskType, model.getObject().getKey()),
+ target).setResourceModel(
+ new StringResourceModel("inner.task.edit",
+ SchedTaskDirectoryPanel.this,
+ Model.of(Pair.of(ActionLink.ActionType.EDIT, model.getObject())))));
}
}, ActionLink.ActionType.EDIT, IdRepoEntitlement.TASK_UPDATE);
@@ -333,13 +288,15 @@ public abstract class SchedTaskDirectoryPanel<T extends SchedTaskTO>
final T clone = SerializationUtils.clone(model.getObject());
clone.setKey(null);
send(SchedTaskDirectoryPanel.this, Broadcast.EXACT,
- new AjaxWizard.EditItemActionEvent<>(clone, target).setResourceModel(
- new StringResourceModel("inner.task.clone",
- SchedTaskDirectoryPanel.this,
- Model.of(Pair.of(ActionLink.ActionType.CLONE, model.getObject())))));
+ new AjaxWizard.EditItemActionEvent<>(clone, target).setResourceModel(
+ new StringResourceModel("inner.task.clone",
+ SchedTaskDirectoryPanel.this,
+ Model.of(Pair.of(ActionLink.ActionType.CLONE, model.getObject())))));
}
}, ActionLink.ActionType.CLONE, IdRepoEntitlement.TASK_CREATE);
+ addFurtherActions(panel, model);
+
panel.add(new ActionLink<>() {
private static final long serialVersionUID = -3722207913631435501L;
@@ -352,8 +309,6 @@ public abstract class SchedTaskDirectoryPanel<T extends SchedTaskTO>
}
}, ActionLink.ActionType.EXECUTE, IdRepoEntitlement.TASK_EXECUTE);
- addFurtherActions(panel, model);
-
panel.add(new ActionLink<>() {
private static final long serialVersionUID = -3722207913631435501L;
@@ -395,19 +350,16 @@ public abstract class SchedTaskDirectoryPanel<T extends SchedTaskTO>
@Override
protected SchedTasksProvider<T> dataProvider() {
- return new SchedTasksProvider<>(reference, taskType, rows);
+ return new SchedTasksProvider<>(taskType, rows);
}
protected static class SchedTasksProvider<T extends SchedTaskTO> extends TaskDataProvider<T> {
private static final long serialVersionUID = 4725679400450513556L;
- private final Class<T> reference;
-
- public SchedTasksProvider(final Class<T> reference, final TaskType taskType, final int paginatorRows) {
+ public SchedTasksProvider(final TaskType taskType, final int paginatorRows) {
super(paginatorRows, taskType);
setSort(Constants.NAME_FIELD_NAME, SortOrder.ASCENDING);
- this.reference = reference;
}
@Override
@@ -418,8 +370,8 @@ public abstract class SchedTaskDirectoryPanel<T extends SchedTaskTO>
@Override
public Iterator<T> iterator(final long first, final long count) {
int page = ((int) first / paginatorRows);
- return TaskRestClient.list(
- reference, (page < 0 ? 0 : page) + 1, paginatorRows, getSort()).
+ return TaskRestClient.<T>list(
+ taskType, (page < 0 ? 0 : page) + 1, paginatorRows, getSort()).
iterator();
}
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder.java
index cbf73b6c8d..2c4c0ce16e 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder.java
@@ -36,6 +36,7 @@ import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDropDownChoiceP
import org.apache.syncope.client.ui.commons.markup.html.form.AjaxPalettePanel;
import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.MacroTaskTO;
import org.apache.syncope.common.lib.to.ProvisioningTaskTO;
import org.apache.syncope.common.lib.to.PullTaskTO;
import org.apache.syncope.common.lib.to.PushTaskTO;
@@ -136,8 +137,8 @@ public class SchedTaskWizardBuilder<T extends SchedTaskTO> extends BaseAjaxWizar
description.setEnabled(true);
add(description);
- AjaxCheckBoxPanel active = new AjaxCheckBoxPanel("active", "active", new PropertyModel<>(taskTO, "active"),
- false);
+ AjaxCheckBoxPanel active = new AjaxCheckBoxPanel(
+ "active", "active", new PropertyModel<>(taskTO, "active"), false);
add(active);
AjaxDropDownChoicePanel<String> jobDelegate = new AjaxDropDownChoicePanel<>(
@@ -147,6 +148,47 @@ public class SchedTaskWizardBuilder<T extends SchedTaskTO> extends BaseAjaxWizar
jobDelegate.setEnabled(taskTO.getKey() == null);
add(jobDelegate);
+ AutoCompleteSettings settings = new AutoCompleteSettings();
+ settings.setShowCompleteListOnFocusGain(!isSearchEnabled);
+ settings.setShowListOnEmptyInput(!isSearchEnabled);
+
+ // ------------------------------
+ // Only for macro tasks
+ // ------------------------------
+ WebMarkupContainer macroTaskSpecifics = new WebMarkupContainer("macroTaskSpecifics");
+ add(macroTaskSpecifics.setRenderBodyOnly(true));
+
+ AjaxSearchFieldPanel realm =
+ new AjaxSearchFieldPanel("realm", "realm",
+ new PropertyModel<>(taskTO, "realm"), settings) {
+
+ private static final long serialVersionUID = -6390474600233486704L;
+
+ @Override
+ protected Iterator<String> getChoices(final String input) {
+ return (RealmsUtils.checkInput(input)
+ ? searchRealms(input).stream().map(RealmTO::getFullPath).collect(Collectors.toList())
+ : List.<String>of()).iterator();
+ }
+ };
+
+ if (taskTO instanceof MacroTaskTO) {
+ realm.addRequiredLabel();
+ if (StringUtils.isBlank(MacroTaskTO.class.cast(taskTO).getRealm())) {
+ // add a default destination realm if missing in the task
+ realm.setModelObject(SyncopeConstants.ROOT_REALM);
+ }
+ }
+ macroTaskSpecifics.add(realm);
+
+ AjaxCheckBoxPanel continueOnError = new AjaxCheckBoxPanel(
+ "continueOnError", "continueOnError", new PropertyModel<>(taskTO, "continueOnError"), false);
+ macroTaskSpecifics.add(continueOnError);
+
+ AjaxCheckBoxPanel saveExecs = new AjaxCheckBoxPanel(
+ "saveExecs", "saveExecs", new PropertyModel<>(taskTO, "saveExecs"), false);
+ macroTaskSpecifics.add(saveExecs);
+
// ------------------------------
// Only for pull tasks
// ------------------------------
@@ -160,7 +202,7 @@ public class SchedTaskWizardBuilder<T extends SchedTaskTO> extends BaseAjaxWizar
pullTaskSpecifics.setEnabled(false).setVisible(false);
}
- final AjaxDropDownChoicePanel<PullMode> pullMode = new AjaxDropDownChoicePanel<>(
+ AjaxDropDownChoicePanel<PullMode> pullMode = new AjaxDropDownChoicePanel<>(
"pullMode", "pullMode", new PropertyModel<>(taskTO, "pullMode"), false);
pullMode.setChoices(List.of(PullMode.values()));
if (taskTO instanceof PullTaskTO) {
@@ -169,7 +211,7 @@ public class SchedTaskWizardBuilder<T extends SchedTaskTO> extends BaseAjaxWizar
pullMode.setNullValid(!(taskTO instanceof PullTaskTO));
pullTaskSpecifics.add(pullMode);
- final AjaxDropDownChoicePanel<String> reconFilterBuilder = new AjaxDropDownChoicePanel<>(
+ AjaxDropDownChoicePanel<String> reconFilterBuilder = new AjaxDropDownChoicePanel<>(
"reconFilterBuilder", "reconFilterBuilder",
new PropertyModel<>(taskTO, "reconFilterBuilder"), false);
reconFilterBuilder.setChoices(reconFilterBuilders.getObject());
@@ -191,11 +233,7 @@ public class SchedTaskWizardBuilder<T extends SchedTaskTO> extends BaseAjaxWizar
}
});
- final AutoCompleteSettings settings = new AutoCompleteSettings();
- settings.setShowCompleteListOnFocusGain(!isSearchEnabled);
- settings.setShowListOnEmptyInput(!isSearchEnabled);
-
- final AjaxSearchFieldPanel destinationRealm =
+ AjaxSearchFieldPanel destinationRealm =
new AjaxSearchFieldPanel("destinationRealm", "destinationRealm",
new PropertyModel<>(taskTO, "destinationRealm"), settings) {
@@ -224,7 +262,7 @@ public class SchedTaskWizardBuilder<T extends SchedTaskTO> extends BaseAjaxWizar
// ------------------------------
// Only for push tasks
- // ------------------------------
+ // ------------------------------
WebMarkupContainer pushTaskSpecifics = new WebMarkupContainer("pushTaskSpecifics");
add(pushTaskSpecifics.setRenderBodyOnly(true));
@@ -232,8 +270,8 @@ public class SchedTaskWizardBuilder<T extends SchedTaskTO> extends BaseAjaxWizar
pushTaskSpecifics.setEnabled(false).setVisible(false);
}
- final AjaxSearchFieldPanel sourceRealm = new AjaxSearchFieldPanel("sourceRealm", "sourceRealm",
- new PropertyModel<>(taskTO, "sourceRealm"), settings) {
+ AjaxSearchFieldPanel sourceRealm = new AjaxSearchFieldPanel(
+ "sourceRealm", "sourceRealm", new PropertyModel<>(taskTO, "sourceRealm"), settings) {
private static final long serialVersionUID = -6390474600233486704L;
@@ -258,8 +296,13 @@ public class SchedTaskWizardBuilder<T extends SchedTaskTO> extends BaseAjaxWizar
if (taskTO instanceof ProvisioningTaskTO) {
jobDelegate.setEnabled(false).setVisible(false);
+ macroTaskSpecifics.setEnabled(false).setVisible(false);
+ } else if (taskTO instanceof MacroTaskTO) {
+ jobDelegate.setEnabled(false).setVisible(false);
+ provisioningTaskSpecifics.setEnabled(false).setVisible(false);
} else {
provisioningTaskSpecifics.setEnabled(false).setVisible(false);
+ macroTaskSpecifics.setEnabled(false).setVisible(false);
}
AjaxPalettePanel<String> actions = new AjaxPalettePanel.Builder<String>().
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTasks.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTasks.java
deleted file mode 100644
index b19b0effaa..0000000000
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTasks.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.tasks;
-
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.client.console.panels.MultilevelPanel;
-import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.SchedTaskTO;
-import org.apache.syncope.common.lib.types.TaskType;
-import org.apache.wicket.PageReference;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.model.Model;
-import org.apache.wicket.model.StringResourceModel;
-
-public class SchedTasks extends AbstractTasks {
-
- private static final long serialVersionUID = -4013796607157549641L;
-
- public <T extends AnyTO> SchedTasks(final BaseModal<?> baseModal, final PageReference pageReference) {
- super(BaseModal.CONTENT_ID);
-
- final MultilevelPanel mlp = new MultilevelPanel("tasks");
- add(mlp);
-
- mlp.setFirstLevel(new SchedTaskDirectoryPanel<>(
- baseModal, mlp, TaskType.SCHEDULED, SchedTaskTO.class, pageReference) {
-
- private static final long serialVersionUID = -2195387360323687302L;
-
- @Override
- protected void viewTask(final SchedTaskTO taskTO, final AjaxRequestTarget target) {
- mlp.next(
- new StringResourceModel("task.view", this, new Model<>(Pair.of(null, taskTO))).getObject(),
- new TaskExecutionDetails<>(baseModal, taskTO, pageReference), target);
- }
- });
- }
-
- public <T extends AnyTO> SchedTasks(final BaseModal<?> baseModal, final PageReference pageReference,
- final boolean wizardInModal, final String id) {
- super(id);
-
- final MultilevelPanel mlp = new MultilevelPanel("tasks");
- add(mlp);
-
- mlp.setFirstLevel(new SchedTaskDirectoryPanel<>(
- baseModal, mlp, TaskType.SCHEDULED, SchedTaskTO.class, pageReference, wizardInModal) {
-
- private static final long serialVersionUID = -2195387360323687302L;
-
- @Override
- protected void viewTask(final SchedTaskTO taskTO, final AjaxRequestTarget target) {
- mlp.next(
- new StringResourceModel("task.view", this, new Model<>(Pair.of(null, taskTO))).getObject(),
- new TaskExecutionDetails<>(baseModal, taskTO, pageReference), target);
- }
- });
- }
-}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/TaskDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/TaskDirectoryPanel.java
index 03cc5d6147..17cd66e533 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/TaskDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/TaskDirectoryPanel.java
@@ -48,31 +48,29 @@ public abstract class TaskDirectoryPanel<T extends TaskTO>
protected final BaseModal<?> baseModal;
- private final MultilevelPanel multiLevelPanelRef;
+ protected final MultilevelPanel multiLevelPanelRef;
protected TaskDirectoryPanel(
- final BaseModal<?> baseModal, final MultilevelPanel multiLevelPanelRef, final PageReference pageRef) {
- super(MultilevelPanel.FIRST_LEVEL_ID, pageRef, false);
- this.baseModal = baseModal;
- this.multiLevelPanelRef = multiLevelPanelRef;
- restClient = new TaskRestClient();
- setShowResultPanel(false);
+ final BaseModal<?> baseModal,
+ final MultilevelPanel multiLevelPanelRef,
+ final PageReference pageRef,
+ final boolean wizardInModal) {
+
+ this(MultilevelPanel.FIRST_LEVEL_ID, baseModal, multiLevelPanelRef, pageRef, wizardInModal);
}
- protected TaskDirectoryPanel(
- final BaseModal<?> baseModal, final MultilevelPanel multiLevelPanelRef, final PageReference pageRef,
- final boolean wizardInModal) {
- super(MultilevelPanel.FIRST_LEVEL_ID, pageRef, wizardInModal);
- this.baseModal = baseModal;
- this.multiLevelPanelRef = multiLevelPanelRef;
- restClient = new TaskRestClient();
- setShowResultPanel(false);
+ protected TaskDirectoryPanel(final String id, final PageReference pageRef) {
+ this(id, null, null, pageRef, false);
}
protected TaskDirectoryPanel(
- final BaseModal<?> baseModal, final MultilevelPanel multiLevelPanelRef, final PageReference pageRef,
- final String id) {
- super(id, pageRef, false);
+ final String id,
+ final BaseModal<?> baseModal,
+ final MultilevelPanel multiLevelPanelRef,
+ final PageReference pageRef,
+ final boolean wizardInModal) {
+
+ super(id, pageRef, wizardInModal);
this.baseModal = baseModal;
this.multiLevelPanelRef = multiLevelPanelRef;
restClient = new TaskRestClient();
@@ -81,10 +79,10 @@ public abstract class TaskDirectoryPanel<T extends TaskTO>
@Override
protected void resultTableCustomChanges(final AjaxDataTablePanel.Builder<T, String> resultTableBuilder) {
- resultTableBuilder.setMultiLevelPanel(baseModal, multiLevelPanelRef);
+ resultTableBuilder.setMultiLevelPanel(multiLevelPanelRef);
}
- protected abstract void viewTask(T taskTO, AjaxRequestTarget target);
+ protected abstract void viewTaskExecs(T taskTO, AjaxRequestTarget target);
protected abstract static class TasksProvider<T extends TaskTO> extends DirectoryDataProvider<T> {
@@ -114,7 +112,7 @@ public abstract class TaskDirectoryPanel<T extends TaskTO>
public void onEvent(final IEvent<?> event) {
super.onEvent(event);
if (event.getPayload() instanceof ExitEvent) {
- final AjaxRequestTarget target = ExitEvent.class.cast(event.getPayload()).getTarget();
+ AjaxRequestTarget target = ExitEvent.class.cast(event.getPayload()).getTarget();
baseModal.show(false);
baseModal.close(target);
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/TaskExecutionDetails.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/TaskExecutionDetails.java
index ef243f3335..1b0cf18c0d 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/TaskExecutionDetails.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/TaskExecutionDetails.java
@@ -20,7 +20,6 @@ package org.apache.syncope.client.console.tasks;
import org.apache.syncope.client.console.panels.MultilevelPanel;
import org.apache.syncope.client.console.rest.TaskRestClient;
-import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
import org.apache.syncope.common.lib.to.TaskTO;
import org.apache.wicket.PageReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -34,13 +33,13 @@ public class TaskExecutionDetails<T extends TaskTO> extends MultilevelPanel.Seco
private static final long serialVersionUID = -4110576026663173545L;
- public TaskExecutionDetails(final BaseModal<?> baseModal, final T taskTO, final PageReference pageRef) {
+ public TaskExecutionDetails(final T taskTO, final PageReference pageRef) {
super();
- final MultilevelPanel mlp = new MultilevelPanel("executions");
+ MultilevelPanel mlp = new MultilevelPanel("executions");
add(mlp);
- mlp.setFirstLevel(new ExecutionsDirectoryPanel(baseModal, mlp, taskTO.getKey(), new TaskRestClient(), pageRef) {
+ mlp.setFirstLevel(new ExecutionsDirectoryPanel(mlp, taskTO.getKey(), new TaskRestClient(), pageRef) {
private static final long serialVersionUID = 5691719817252887541L;
@@ -49,6 +48,7 @@ public class TaskExecutionDetails<T extends TaskTO> extends MultilevelPanel.Seco
final String title,
final MultilevelPanel.SecondLevel slevel,
final AjaxRequestTarget target) {
+
mlp.next(title, slevel, target);
}
});
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksTogglePanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksTogglePanel.java
index b22eb5c37b..caf67cb5ae 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksTogglePanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksTogglePanel.java
@@ -27,12 +27,14 @@ import org.apache.syncope.client.console.panels.TogglePanel;
import org.apache.syncope.client.console.panels.ToggleableTarget;
import org.apache.syncope.client.console.policies.PolicyRuleWrapper;
import org.apache.syncope.client.console.reports.ReportletWrapper;
+import org.apache.syncope.client.console.tasks.CommandWrapper;
import org.apache.syncope.client.console.wizards.any.GroupWrapper;
import org.apache.syncope.client.ui.commons.status.StatusBean;
import org.apache.syncope.client.ui.commons.wizards.any.AnyWrapper;
import org.apache.syncope.client.ui.commons.wizards.any.UserWrapper;
import org.apache.syncope.common.keymaster.client.api.model.Domain;
import org.apache.syncope.common.lib.Attr;
+import org.apache.syncope.common.lib.command.CommandTO;
import org.apache.syncope.common.lib.policy.PolicyTO;
import org.apache.syncope.common.lib.to.AccessTokenTO;
import org.apache.syncope.common.lib.to.AnyObjectTO;
@@ -104,6 +106,8 @@ public class ActionLinksTogglePanel<T extends Serializable> extends TogglePanel<
header = ((PolicyRuleWrapper) modelObject).getImplementationKey();
} else if (modelObject instanceof ReportletWrapper) {
header = ((ReportletWrapper) modelObject).getImplementationKey();
+ } else if (modelObject instanceof CommandWrapper) {
+ header = ((CommandWrapper) modelObject).getCommand().getKey();
} else if (modelObject instanceof JobTO) {
header = ((JobTO) modelObject).getRefKey() == null
? ((JobTO) modelObject).getRefDesc() : ((JobTO) modelObject).getRefKey();
@@ -111,6 +115,8 @@ public class ActionLinksTogglePanel<T extends Serializable> extends TogglePanel<
header = ((ToggleableTarget) modelObject).getAnyType();
} else if (modelObject instanceof Domain) {
header = ((Domain) modelObject).getKey();
+ } else if (modelObject instanceof CommandTO) {
+ header = ((CommandTO) modelObject).getKey();
} else if (modelObject instanceof NamedEntityTO) {
header = ((NamedEntityTO) modelObject).getName();
} else if (modelObject instanceof EntityTO) {
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ConfirmBehavior.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ConfirmBehavior.java
index 19deec2e6d..c4f0218a57 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ConfirmBehavior.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ConfirmBehavior.java
@@ -55,6 +55,14 @@ public class ConfirmBehavior extends Behavior {
+ " evt.stopImmediatePropagation();"
+ " bootbox.confirm({"
+ "message:'" + new ResourceModel(msg).getObject() + "', "
+ + "buttons: {"
+ + " confirm: {"
+ + " className: 'btn-success'"
+ + " },"
+ + " cancel: {"
+ + " className: 'btn-danger'"
+ + " }"
+ + "},"
+ "locale: '" + SyncopeConsoleSession.get().getLocale().getLanguage() + "',"
+ "callback: function(result) {"
+ " if (result == true) {"
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/JobWidget.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/JobWidget.java
index 9424c83f41..8bdbfbc660 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/JobWidget.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/JobWidget.java
@@ -225,7 +225,7 @@ public class JobWidget extends BaseWidget {
}
private List<ITab> buildTabList(final PageReference pageRef) {
- final List<ITab> tabs = new ArrayList<>();
+ List<ITab> tabs = new ArrayList<>();
tabs.add(new AbstractTab(new ResourceModel("available")) {
@@ -324,9 +324,9 @@ public class JobWidget extends BaseWidget {
@Override
public void populateItem(
- final Item<ICellPopulator<JobTO>> cellItem,
- final String componentId,
- final IModel<JobTO> rowModel) {
+ final Item<ICellPopulator<JobTO>> cellItem,
+ final String componentId,
+ final IModel<JobTO> rowModel) {
JobTO jobTO = rowModel.getObject();
JobActionPanel panel = new JobActionPanel(componentId, jobTO, true, JobWidget.this);
@@ -335,17 +335,17 @@ public class JobWidget extends BaseWidget {
switch (jobTO.getType()) {
case TASK:
roles = String.format("%s,%s",
- IdRepoEntitlement.TASK_EXECUTE, IdRepoEntitlement.TASK_UPDATE);
+ IdRepoEntitlement.TASK_EXECUTE, IdRepoEntitlement.TASK_UPDATE);
break;
case REPORT:
roles = String.format("%s,%s",
- IdRepoEntitlement.REPORT_EXECUTE, IdRepoEntitlement.REPORT_UPDATE);
+ IdRepoEntitlement.REPORT_EXECUTE, IdRepoEntitlement.REPORT_UPDATE);
break;
case NOTIFICATION:
roles = String.format("%s,%s",
- IdRepoEntitlement.NOTIFICATION_EXECUTE, IdRepoEntitlement.NOTIFICATION_UPDATE);
+ IdRepoEntitlement.NOTIFICATION_EXECUTE, IdRepoEntitlement.NOTIFICATION_UPDATE);
break;
default:
@@ -358,7 +358,7 @@ public class JobWidget extends BaseWidget {
@Override
public String getCssClass() {
- return "col-xs-1";
+ return "running-col";
}
});
@@ -390,9 +390,9 @@ public class JobWidget extends BaseWidget {
target.add(jobModal.setContent(rwb.build(BaseModal.CONTENT_ID, AjaxWizard.Mode.EDIT)));
jobModal.header(new StringResourceModel(
- "any.edit",
- AvailableJobsPanel.this,
- new Model<>(reportTO)));
+ "any.edit",
+ AvailableJobsPanel.this,
+ new Model<>(reportTO)));
jobModal.show(true);
break;
@@ -403,21 +403,21 @@ public class JobWidget extends BaseWidget {
schedTaskTO = TaskRestClient.readTask(TaskType.PULL, jobTO.getRefKey());
} catch (Exception e) {
LOG.debug("Failed to read {} as {}, attempting {}",
- jobTO.getRefKey(), TaskType.PULL, TaskType.PUSH, e);
+ jobTO.getRefKey(), TaskType.PULL, TaskType.PUSH, e);
schedTaskTO = TaskRestClient.readTask(TaskType.PUSH, jobTO.getRefKey());
}
SchedTaskWizardBuilder<ProvisioningTaskTO> swb =
- new SchedTaskWizardBuilder<>(schedTaskTO instanceof PullTaskTO
- ? TaskType.PULL : TaskType.PUSH, schedTaskTO, pageRef);
+ new SchedTaskWizardBuilder<>(schedTaskTO instanceof PullTaskTO
+ ? TaskType.PULL : TaskType.PUSH, schedTaskTO, pageRef);
swb.setEventSink(AvailableJobsPanel.this);
target.add(jobModal.setContent(swb.build(BaseModal.CONTENT_ID, AjaxWizard.Mode.EDIT)));
jobModal.header(new StringResourceModel(
- "any.edit",
- AvailableJobsPanel.this,
- new Model<>(schedTaskTO)));
+ "any.edit",
+ AvailableJobsPanel.this,
+ new Model<>(schedTaskTO)));
jobModal.show(true);
break;
@@ -451,14 +451,14 @@ public class JobWidget extends BaseWidget {
final ReportTO reportTO = ReportRestClient.read(jobTO.getRefKey());
target.add(AvailableJobsPanel.this.reportModal.setContent(
- new ReportletDirectoryPanel(reportModal, jobTO.getRefKey(), pageRef)));
+ new ReportletDirectoryPanel(reportModal, jobTO.getRefKey(), pageRef)));
MetaDataRoleAuthorizationStrategy.authorize(
- reportModal.getForm(),
- ENABLE, IdRepoEntitlement.REPORT_UPDATE);
+ reportModal.getForm(),
+ ENABLE, IdRepoEntitlement.REPORT_UPDATE);
reportModal.header(new StringResourceModel(
- "reportlet.conf", AvailableJobsPanel.this, new Model<>(reportTO)));
+ "reportlet.conf", AvailableJobsPanel.this, new Model<>(reportTO)));
reportModal.show(true);
@@ -476,7 +476,7 @@ public class JobWidget extends BaseWidget {
@Override
protected boolean statusCondition(final JobTO modelObject) {
return !(null != jobTO.getType() && (JobType.TASK.equals(jobTO.getType())
- || JobType.NOTIFICATION.equals(jobTO.getType())));
+ || JobType.NOTIFICATION.equals(jobTO.getType())));
}
}, ActionType.COMPOSE, IdRepoEntitlement.TASK_UPDATE);
@@ -518,8 +518,8 @@ public class JobWidget extends BaseWidget {
@Override
protected boolean statusCondition(final JobTO modelObject) {
return (null != jobTO.getType()
- && !JobType.NOTIFICATION.equals(jobTO.getType())
- && (jobTO.isScheduled() && !jobTO.isRunning()));
+ && !JobType.NOTIFICATION.equals(jobTO.getType())
+ && (jobTO.isScheduled() && !jobTO.isRunning()));
}
}, ActionLink.ActionType.DELETE, IdRepoEntitlement.TASK_DELETE, true);
@@ -625,7 +625,7 @@ public class JobWidget extends BaseWidget {
@Override
public ActionsPanel<ExecTO> getActions(final IModel<ExecTO> model) {
- final ActionsPanel<ExecTO> panel = super.getActions(model);
+ ActionsPanel<ExecTO> panel = super.getActions(model);
panel.add(new ActionLink<>() {
@@ -639,6 +639,7 @@ public class JobWidget extends BaseWidget {
target.add(detailModal);
}
}, ActionLink.ActionType.VIEW, IdRepoEntitlement.TASK_READ);
+
return panel;
}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/CommandWizardBuilder.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/CommandWizardBuilder.java
new file mode 100644
index 0000000000..cd27db62e6
--- /dev/null
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/CommandWizardBuilder.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.wizards;
+
+import java.io.Serializable;
+import org.apache.syncope.client.console.panels.BeanPanel;
+import org.apache.syncope.client.console.rest.CommandRestClient;
+import org.apache.syncope.common.lib.command.CommandTO;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.extensions.wizard.WizardModel;
+import org.apache.wicket.extensions.wizard.WizardStep;
+import org.apache.wicket.model.LoadableDetachableModel;
+
+public class CommandWizardBuilder extends BaseAjaxWizardBuilder<CommandTO> {
+
+ private static final long serialVersionUID = 5288806466136582164L;
+
+ public CommandWizardBuilder(final CommandTO defaultItem, final PageReference pageRef) {
+ super(defaultItem, pageRef);
+ }
+
+ @Override
+ protected Serializable onApplyInternal(final CommandTO modelObject) {
+ return CommandRestClient.run(modelObject).getOutput();
+ }
+
+ @Override
+ protected WizardModel buildModelSteps(final CommandTO modelObject, final WizardModel wizardModel) {
+ wizardModel.add(new CommandArgs(modelObject));
+ return wizardModel;
+ }
+
+ public class CommandArgs extends WizardStep {
+
+ private static final long serialVersionUID = -785981096328637758L;
+
+ public CommandArgs(final CommandTO command) {
+ LoadableDetachableModel<Serializable> bean = new LoadableDetachableModel<>() {
+
+ private static final long serialVersionUID = -1096114645494621802L;
+
+ @Override
+ protected Serializable load() {
+ return command.getArgs();
+ }
+ };
+ add(new BeanPanel<>("bean", bean, pageRef).setRenderBodyOnly(true));
+ }
+ }
+}
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java
index 20b36d2f6c..c79f0bde58 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java
@@ -227,13 +227,12 @@ public abstract class WizardMgtPanel<T extends Serializable> extends AbstractWiz
target.ifPresent(this::customActionOnCancelCallback);
} else if (event.getPayload() instanceof AjaxWizard.NewItemFinishEvent) {
SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
- target.ifPresent(ajaxRequestTarget ->
- ((BaseWebPage) pageRef.getPage()).getNotificationPanel().refresh(ajaxRequestTarget));
+ target.ifPresent(t -> ((BaseWebPage) pageRef.getPage()).getNotificationPanel().refresh(t));
if (wizardInModal && showResultPanel) {
modal.setContent(new ResultPanel<>(
- item,
- AjaxWizard.NewItemFinishEvent.class.cast(newItemEvent).getResult()) {
+ item,
+ AjaxWizard.NewItemFinishEvent.class.cast(newItemEvent).getResult()) {
private static final long serialVersionUID = -2630573849050255233L;
@@ -243,8 +242,11 @@ public abstract class WizardMgtPanel<T extends Serializable> extends AbstractWiz
}
@Override
- protected Panel customResultBody(final String panelId, final T item,
+ protected Panel customResultBody(
+ final String panelId,
+ final T item,
final Serializable result) {
+
return WizardMgtPanel.this.customResultBody(panelId, item, result);
}
});
diff --git a/client/idrepo/console/src/main/resources/META-INF/resources/css/syncopeConsole.scss b/client/idrepo/console/src/main/resources/META-INF/resources/css/syncopeConsole.scss
index 6d62576586..1deeea07ab 100644
--- a/client/idrepo/console/src/main/resources/META-INF/resources/css/syncopeConsole.scss
+++ b/client/idrepo/console/src/main/resources/META-INF/resources/css/syncopeConsole.scss
@@ -96,9 +96,12 @@ body {
}
}
+/* JSON diff
+============================================================================= */
+
.json-diff-header {
text-align: center;
-
+
display: table;
width: 100%;
table-layout: fixed;
@@ -109,3 +112,7 @@ body {
display: table-cell;
vertical-align: middle;
}
+
+.running-col {
+ width: 65px;
+}
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication.properties
index 966af0ddad..e013427500 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication.properties
@@ -80,3 +80,5 @@ domains=Domains
nomatch=No matches found
tooLargeFile=File is too large, max upload file size is ${maxUploadSizeB} bytes (${maxUploadSizeMB} MB).
confirmDelegation=Do you really want to switch user?
+topology=Topology
+engagements=Engagements
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication_fr_CA.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication_fr_CA.properties
index de288344fb..90301999a4 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication_fr_CA.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication_fr_CA.properties
@@ -79,3 +79,4 @@ domains=Domaines
nomatch=Aucune correspondance trouv\u00e9e
tooLargeFile=Fichier trop volumineux, la taille maximale autoris\u00e9e est de $ {maxUploadSizeB} octets ($ {maxUploadSizeMB} Mo).
confirmDelegation=Do you really want to switch user?
+engagements=Engagements
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication_it.properties
index 59c56dc705..3200a9be9d 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication_it.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication_it.properties
@@ -80,3 +80,5 @@ domains=Domini
nomatch=Nessun risultato trovato
tooLargeFile=File troppo grande, la dimensione massima ammessa \u00e8 ${maxUploadSizeB} bytes (${maxUploadSizeMB} MB).
confirmDelegation=Vuoi davvero cambiare utenza?
+topology=Topologia
+engagements=Impegni
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication_ja.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication_ja.properties
index ca0e84ecd7..a4ed95c701 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication_ja.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication_ja.properties
@@ -78,3 +78,5 @@ domains=\u30c9\u30e1\u30a4\u30f3
nomatch=No matches found
tooLargeFile=File is too large, max upload file size is ${maxUploadSizeB} bytes (${maxUploadSizeMB} MB).
confirmDelegation=Do you really want to switch user?
+topology=Topology
+engagements=Engagements
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication_pt_BR.properties
index 142ca0eb03..cd5fe7769e 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication_pt_BR.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication_pt_BR.properties
@@ -80,3 +80,5 @@ domains=Dom\u00ednios
nomatch=Nenhuma correspond\u00eancia encontrada
tooLargeFile=File is too large, max upload file size is ${maxUploadSizeB} bytes (${maxUploadSizeMB} MB).
confirmDelegation=Do you really want to switch user?
+topology=Topology
+engagements=Engagements
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication_ru.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication_ru.properties
index 9c58582f02..dd5cd0fbc2 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication_ru.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/SyncopeWebApplication_ru.properties
@@ -79,3 +79,5 @@ domains=Domains
nomatch=No matches found
tooLargeFile=File is too large, max upload file size is ${maxUploadSizeB} bytes (${maxUploadSizeMB} MB).
confirmDelegation=Do you really want to switch user?
+topology=Topology
+engagements=Engagements
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyRecipientsProvider.groovy b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyCommand.groovy
similarity index 69%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyRecipientsProvider.groovy
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyCommand.groovy
index 6009cf9ea0..3b59310f2a 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyRecipientsProvider.groovy
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyCommand.groovy
@@ -1,3 +1,4 @@
+
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -17,15 +18,13 @@
* under the License.
*/
import groovy.transform.CompileStatic
-import org.apache.syncope.core.persistence.api.attrvalue.validation.Validator
-import org.apache.syncope.core.persistence.api.entity.Notification
-import org.apache.syncope.core.provisioning.api.notification.RecipientsProvider
+import org.apache.syncope.common.lib.command.CommandArgs
+import org.apache.syncope.core.logic.api.Command
@CompileStatic
-class MyRecipientsProvider implements RecipientsProvider {
-
- @Override
- Set<String> provideRecipients(Notification notification) {
- return List.of();
+class MyCommand implements Command<CommandArgs> {
+
+ String run(CommandArgs args) {
+ return "SUCCESS"
}
}
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyLogicActions.groovy b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyLogicActions.groovy
index f92be605ec..b176acd1d1 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyLogicActions.groovy
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyLogicActions.groovy
@@ -21,7 +21,7 @@ import org.apache.syncope.common.lib.request.AnyCR
import org.apache.syncope.common.lib.request.AnyUR
import org.apache.syncope.common.lib.to.AnyTO
import org.apache.syncope.common.lib.to.PropagationStatus
-import org.apache.syncope.core.provisioning.api.LogicActions
+import org.apache.syncope.core.logic.api.LogicActions
@CompileStatic
class MyLogicActions implements LogicActions {
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyRecipientsProvider.groovy b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyRecipientsProvider.groovy
index 6009cf9ea0..1fe53ff713 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyRecipientsProvider.groovy
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyRecipientsProvider.groovy
@@ -17,7 +17,7 @@
* under the License.
*/
import groovy.transform.CompileStatic
-import org.apache.syncope.core.persistence.api.attrvalue.validation.Validator
+import java.util.Set
import org.apache.syncope.core.persistence.api.entity.Notification
import org.apache.syncope.core.provisioning.api.notification.RecipientsProvider
@@ -26,6 +26,6 @@ class MyRecipientsProvider implements RecipientsProvider {
@Override
Set<String> provideRecipients(Notification notification) {
- return List.of();
+ return Set.of();
}
}
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage.html
index 505bbf2ee4..7ca271e928 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage.html
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage.html
@@ -127,6 +127,7 @@ under the License.
<ul class="nav nav-pills nav-sidebar flex-column nav-child-indent nav-compact" data-widget="treeview" role="menu" data-accordion="false">
<li class="nav-item" wicket:id="dashboardLI"><a href="#" class="nav-link" wicket:id="dashboard"><i class="nav-icon fa fa-tachometer-alt"></i><p><wicket:message key="dashboard"/></p></a></li>
<li class="nav-item" wicket:id="realmsLI"><a href="#" class="nav-link" wicket:id="realms"><i class="nav-icon fa fa-folder-open"></i><p><wicket:message key="realms"/></p></a></li>
+ <li class="nav-item" wicket:id="engagementsLI"><a href="#" class="nav-link" wicket:id="engagements"><i class="nav-icon fas fa-tasks"></i><p><wicket:message key="engagements"/></p></a></li>
<li class="nav-item" wicket:id="reportsLI"><a href="#" class="nav-link" wicket:id="reports"><i class="nav-icon fa fa-chart-pie"></i><p><wicket:message key="reports"/></p></a></li>
<wicket:container wicket:id="idmPages">
<li class="nav-item" wicket:id="idmPageLI">
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Engagements.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Engagements.html
new file mode 100644
index 0000000000..0a67f877c9
--- /dev/null
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Engagements.html
@@ -0,0 +1,47 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+ <wicket:extend>
+ <section class="content-header">
+ <div class="container-fluid">
+ <div class="row mb-2">
+ <div class="col-sm-6">
+ <h1> </h1>
+ </div>
+ <div class="col-sm-6">
+ <ol class="breadcrumb float-sm-right">
+ <li class="breadcrumb-item">
+ <a wicket:id="dashboardBr"><i class="fa fa-tachometer-alt"></i> <wicket:message key="dashboard"></wicket:message></a>
+ </li>
+ <li class="breadcrumb-item active"><wicket:message key="engagements"/></li>
+ </ol>
+ </div>
+ </div>
+ </div><!-- /.container-fluid -->
+ </section>
+
+ <section class="content" wicket:id="content">
+ <div class="container-fluid">
+ <div class="card card-outline">
+ <div class="card-body" wicket:id="tabbedPanel"/>
+ </div>
+ </div>
+ </section>
+ </wicket:extend>
+</html>
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Engagements.properties
similarity index 88%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Engagements.properties
index 78e6676a99..f46483841f 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Engagements.properties
@@ -14,5 +14,9 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-reports=Reports
-report.templates=Templates
+
+schedTasks=Scheduled Tasks
+macroTasks=Macro
+commands=Commands
+arguments=Arguments
+any.edit=Run ${key}
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Engagements_fr_CA.properties
similarity index 88%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Engagements_fr_CA.properties
index 78e6676a99..f46483841f 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Engagements_fr_CA.properties
@@ -14,5 +14,9 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-reports=Reports
-report.templates=Templates
+
+schedTasks=Scheduled Tasks
+macroTasks=Macro
+commands=Commands
+arguments=Arguments
+any.edit=Run ${key}
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Engagements_it.properties
similarity index 88%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_pt_BR.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Engagements_it.properties
index e675da7407..da0fafe645 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_pt_BR.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Engagements_it.properties
@@ -14,5 +14,9 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-reports=Reports
-report.templates=Template
+
+schedTasks=Task Programmati
+macroTasks=Macro
+commands=Comandi
+arguments=Argomenti
+any.edit=Esegui ${key}
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Engagements_ja.properties
similarity index 88%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Engagements_ja.properties
index 78e6676a99..f46483841f 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Engagements_ja.properties
@@ -14,5 +14,9 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-reports=Reports
-report.templates=Templates
+
+schedTasks=Scheduled Tasks
+macroTasks=Macro
+commands=Commands
+arguments=Arguments
+any.edit=Run ${key}
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Engagements_pt_BR.properties
similarity index 87%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_pt_BR.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Engagements_pt_BR.properties
index e675da7407..39b6776c98 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_pt_BR.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Engagements_pt_BR.properties
@@ -14,5 +14,9 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-reports=Reports
-report.templates=Template
+
+schedTasks=ScheduledScheduled Tasks
+macroTasks=Macro
+commands=Commands
+arguments=Arguments
+any.edit=Run ${key}
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Engagements_ru.properties
similarity index 88%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Engagements_ru.properties
index 78e6676a99..f46483841f 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Engagements_ru.properties
@@ -14,5 +14,9 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-reports=Reports
-report.templates=Templates
+
+schedTasks=Scheduled Tasks
+macroTasks=Macro
+commands=Commands
+arguments=Arguments
+any.edit=Run ${key}
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports.properties
index 78e6676a99..a13d504168 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports.properties
@@ -14,5 +14,5 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-reports=Reports
+
report.templates=Templates
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_it.properties
index 732d43d536..7a2a58b8ac 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_it.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_it.properties
@@ -14,5 +14,5 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-reports=Report
+
report.templates=Template
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_ja.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_ja.properties
index eaec821347..2c4b891886 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_ja.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_ja.properties
@@ -14,5 +14,5 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-reports=\u30ec\u30dd\u30fc\u30c8
+
report.templates=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_pt_BR.properties
index e675da7407..7a2a58b8ac 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_pt_BR.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_pt_BR.properties
@@ -14,5 +14,5 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-reports=Reports
+
report.templates=Template
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_ru.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_ru.properties
index c1a1b3f815..bd7b281867 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_ru.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_ru.properties
@@ -14,6 +14,5 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-#
-reports=\u041e\u0442\u0447\u0435\u0442\u044b
+
report.templates=\u0428\u0430\u0431\u043b\u043e\u043d\u044b
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/CommandsPanel.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/CommandsPanel.html
new file mode 100644
index 0000000000..9375b3de50
--- /dev/null
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/CommandsPanel.html
@@ -0,0 +1,36 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+ <wicket:panel>
+ <div wicket:id="searchBox">
+ <form wicket:id="form">
+ <div class="input-group mb-3">
+ <span wicket:id="filter">[FILTER]</span>
+ <span class="input-group-btn">
+ <button type="button" class="btn btn-default btn-flat" wicket:id="search">
+ <span class="fas fa-search" aria-hidden="true"></span>
+ </button>
+ </span>
+ </div>
+ </form>
+ </div>
+
+ <div wicket:id="commands"></div>
+ </wicket:panel>
+</html>
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/CommandComposeWizardBuilder$CommandArgs.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/CommandComposeWizardBuilder$CommandArgs.html
new file mode 100644
index 0000000000..7772c93b7b
--- /dev/null
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/CommandComposeWizardBuilder$CommandArgs.html
@@ -0,0 +1,23 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+ <wicket:panel>
+ <span wicket:id="bean"/>
+ </wicket:panel>
+</html>
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/CommandComposeWizardBuilder$Profile.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/CommandComposeWizardBuilder$Profile.html
new file mode 100644
index 0000000000..8f5d94de16
--- /dev/null
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/CommandComposeWizardBuilder$Profile.html
@@ -0,0 +1,26 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+ <wicket:panel>
+ <div class="form-group">
+ <label for="command"><wicket:message key="command"/></label>
+ <input type="text" class="form-control col-xs-4" wicket:id="command"/>
+ </div>
+ </wicket:panel>
+</html>
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/CommandComposeWizardBuilder$Profile.properties
similarity index 95%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_it.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/CommandComposeWizardBuilder$Profile.properties
index 732d43d536..8b0724c04b 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_it.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/CommandComposeWizardBuilder$Profile.properties
@@ -14,5 +14,5 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-reports=Report
-report.templates=Template
+
+command=Command
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/CommandComposeWizardBuilder$Profile_fr_CA.properties
similarity index 95%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_it.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/CommandComposeWizardBuilder$Profile_fr_CA.properties
index 732d43d536..8b0724c04b 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_it.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/CommandComposeWizardBuilder$Profile_fr_CA.properties
@@ -14,5 +14,5 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-reports=Report
-report.templates=Template
+
+command=Command
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/CommandComposeWizardBuilder$Profile_it.properties
similarity index 95%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_it.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/CommandComposeWizardBuilder$Profile_it.properties
index 732d43d536..91b2647095 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_it.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/CommandComposeWizardBuilder$Profile_it.properties
@@ -14,5 +14,5 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-reports=Report
-report.templates=Template
+
+command=Comando
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/CommandComposeWizardBuilder$Profile_ja.properties
similarity index 95%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_it.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/CommandComposeWizardBuilder$Profile_ja.properties
index 732d43d536..8b0724c04b 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_it.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/CommandComposeWizardBuilder$Profile_ja.properties
@@ -14,5 +14,5 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-reports=Report
-report.templates=Template
+
+command=Command
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/CommandComposeWizardBuilder$Profile_pt_BR.properties
similarity index 95%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_it.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/CommandComposeWizardBuilder$Profile_pt_BR.properties
index 732d43d536..8b0724c04b 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_it.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/CommandComposeWizardBuilder$Profile_pt_BR.properties
@@ -14,5 +14,5 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-reports=Report
-report.templates=Template
+
+command=Command
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/CommandComposeWizardBuilder$Profile_ru.properties
similarity index 95%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_it.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/CommandComposeWizardBuilder$Profile_ru.properties
index 732d43d536..8b0724c04b 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_it.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/CommandComposeWizardBuilder$Profile_ru.properties
@@ -14,5 +14,5 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-reports=Report
-report.templates=Template
+
+command=Command
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/MacroTaskDirectoryPanel.properties
similarity index 87%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_pt_BR.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/MacroTaskDirectoryPanel.properties
index e675da7407..2c072ba2df 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_pt_BR.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/MacroTaskDirectoryPanel.properties
@@ -14,5 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-reports=Reports
-report.templates=Template
+
+command.conf=Command configuration for ${name}
+continueOnError=Continue on error
+saveExecs=Save executions
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/MacroTaskDirectoryPanel_fr_CA.properties
similarity index 87%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_pt_BR.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/MacroTaskDirectoryPanel_fr_CA.properties
index e675da7407..2c072ba2df 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_pt_BR.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/MacroTaskDirectoryPanel_fr_CA.properties
@@ -14,5 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-reports=Reports
-report.templates=Template
+
+command.conf=Command configuration for ${name}
+continueOnError=Continue on error
+saveExecs=Save executions
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/MacroTaskDirectoryPanel_it.properties
similarity index 86%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_pt_BR.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/MacroTaskDirectoryPanel_it.properties
index e675da7407..91e32ecf6e 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_pt_BR.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/MacroTaskDirectoryPanel_it.properties
@@ -14,5 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-reports=Reports
-report.templates=Template
+
+command.conf=Configurazione dei comandi per ${name}
+continueOnError=Continuare in caso di errore
+saveExecs=Salvare esecuzioni
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/MacroTaskDirectoryPanel_ja.properties
similarity index 87%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_pt_BR.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/MacroTaskDirectoryPanel_ja.properties
index e675da7407..2c072ba2df 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_pt_BR.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/MacroTaskDirectoryPanel_ja.properties
@@ -14,5 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-reports=Reports
-report.templates=Template
+
+command.conf=Command configuration for ${name}
+continueOnError=Continue on error
+saveExecs=Save executions
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/MacroTaskDirectoryPanel_pt_BR.properties
similarity index 87%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_pt_BR.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/MacroTaskDirectoryPanel_pt_BR.properties
index e675da7407..2c072ba2df 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_pt_BR.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/MacroTaskDirectoryPanel_pt_BR.properties
@@ -14,5 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-reports=Reports
-report.templates=Template
+
+command.conf=Command configuration for ${name}
+continueOnError=Continue on error
+saveExecs=Save executions
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/MacroTaskDirectoryPanel_ru.properties
similarity index 87%
copy from client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_pt_BR.properties
copy to client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/MacroTaskDirectoryPanel_ru.properties
index e675da7407..2c072ba2df 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Reports_pt_BR.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/MacroTaskDirectoryPanel_ru.properties
@@ -14,5 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-reports=Reports
-report.templates=Template
+
+command.conf=Command configuration for ${name}
+continueOnError=Continue on error
+saveExecs=Save executions
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.properties
index a14b3f6141..70dbbd8e89 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.properties
@@ -30,3 +30,4 @@ pullMode=Pull Mode
reconFilterBuilder=Reconciliation Filter Builder
actions=Actions
sourceRealm=Source Realm
+realm=Realm
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel_fr_CA.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel_fr_CA.properties
index 4fdb593d21..cc45c5c4fa 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel_fr_CA.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel_fr_CA.properties
@@ -17,15 +17,16 @@
name=Nom
description=Description
destinationRealm=Domaine de destination
-jobDelegate=D�l�gu� � la t�che
-lastExec=Derni�re ex�cution
-nextExec=Prochaine ex�cution
+jobDelegate=D\u00e9l\u00e9gu\u00e9 \u00e0 la t\u00e2che
+lastExec=Derni\u00e8re ex\u00e9cution
+nextExec=Prochaine ex\u00e9cution
active=Actif
any.edit=Modifier ${name}
-any.new=Nouvelle t�che
+any.new=Nouvelle t\u00e2che
any.finish=Soumettre ${name}
any.cancel=Annuler ${name}
pullMode=Mode Extraction
-reconFilterBuilder=G�n�rateur de filtre de rapprochement
+reconFilterBuilder=G\u00e9n\u00e9rateur de filtre de rapprochement
actions=Actions
sourceRealm=Domaine source
+realm=Realm
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel_it.properties
index f261aec1b2..0444fd6dc5 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel_it.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel_it.properties
@@ -30,3 +30,4 @@ pullMode=Pull Mode
reconFilterBuilder=Reconciliation Filter Builder
actions=Actions
sourceRealm=Realm sorgente
+realm=Realm
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel_ja.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel_ja.properties
index e30d011da2..8d8cf9bfb9 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel_ja.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel_ja.properties
@@ -30,3 +30,4 @@ pullMode=\u30d7\u30eb\u30e2\u30fc\u30c9
reconFilterBuilder=\u30d5\u30a3\u30eb\u30bf\u30fc\u30d3\u30eb\u30c0\u30fc\u306e\u7167\u5408
actions=\u30a2\u30af\u30b7\u30e7\u30f3
sourceRealm=\u30bd\u30fc\u30b9\u30ec\u30eb\u30e0
+realm=Realm
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel_pt_BR.properties
index a14b3f6141..70dbbd8e89 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel_pt_BR.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel_pt_BR.properties
@@ -30,3 +30,4 @@ pullMode=Pull Mode
reconFilterBuilder=Reconciliation Filter Builder
actions=Actions
sourceRealm=Source Realm
+realm=Realm
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel_ru.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel_ru.properties
index 9339ef79ad..99490c04cd 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel_ru.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel_ru.properties
@@ -41,3 +41,4 @@ pullMode=\u0420\u0435\u0436\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u04
reconFilterBuilder=\u0424\u0438\u043b\u044c\u0442\u0440 \u0440\u0435\u043a\u043e\u043d\u0441\u0438\u043b\u0438\u0430\u0446\u0438\u0438
actions=\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u044f
sourceRealm=Source Realm
+realm=Realm
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder$Profile.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder$Profile.html
index 56ceeea006..a4b5615847 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder$Profile.html
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder$Profile.html
@@ -24,6 +24,12 @@ under the License.
<div class="form-group"><span wicket:id="jobDelegate">[jobDelegate]</span></div>
+ <span wicket:id="macroTaskSpecifics">
+ <div class="form-group"><span wicket:id="realm">[realm]</span></div>
+ <div class="form-group"><span wicket:id="continueOnError">[continueOnError]</span></div>
+ <div class="form-group"><span wicket:id="saveExecs">[saveExecs]</span></div>
+ </span>
+
<span wicket:id="pullTaskSpecifics">
<div class="form-group"><span wicket:id="destinationRealm">[destinationRealm]</span></div>
<div class="form-group"><span wicket:id="pullMode">[pullMode]</span></div>
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder$Profile_fr_CA.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder$Profile_fr_CA.properties
index e034aac3d6..4c3c876a23 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder$Profile_fr_CA.properties
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder$Profile_fr_CA.properties
@@ -17,18 +17,18 @@
name=Nom
description=Description
jobDelegate=Classe
-matchingRule=R�gle correspondante
-unmatchingRule=R�gle non correspondante
-performCreate=Permettre cr�ation
-performUpdate=Permettre mise ďż˝ jour
+matchingRule=R\u00e8gle correspondante
+unmatchingRule=R\u00e8gle non correspondante
+performCreate=Permettre cr\u00e9ation
+performUpdate=Permettre mise \u00e0 jour
performDelete=Permettre suppression
syncStatus=Statut sync
-lastExec=Derni�re ex�cution
-nextExec=Prochaine ex�cution
-detail=D�tails
+lastExec=Derni\u00e8re ex\u00e9cution
+nextExec=Prochaine ex\u00e9cution
+detail=D\u00e9tails
delete=Supprimer
edit=Modifier
-execute=Ex�cuter
-executeDryRun=Test ďż˝ blanc
+execute=Ex\u00e9cuter
+executeDryRun=Test \u00e0 blanc
latestExecStatus=Dernier statut
-remediation=Remise en �tat
+remediation=Remise en \u00e9tat
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/CommandWizardBuilder$CommandArgs.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/CommandWizardBuilder$CommandArgs.html
new file mode 100644
index 0000000000..7772c93b7b
--- /dev/null
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/CommandWizardBuilder$CommandArgs.html
@@ -0,0 +1,23 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+ <wicket:panel>
+ <span wicket:id="bean"/>
+ </wicket:panel>
+</html>
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/TaskUtils.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/command/CommandArgs.java
similarity index 67%
copy from core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/TaskUtils.java
copy to common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/command/CommandArgs.java
index e8f5c15d38..5a66bae16d 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/TaskUtils.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/command/CommandArgs.java
@@ -16,20 +16,14 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.syncope.core.persistence.api.entity.task;
+package org.apache.syncope.common.lib.command;
-import org.apache.syncope.common.lib.to.TaskTO;
-import org.apache.syncope.common.lib.types.TaskType;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import org.apache.syncope.common.lib.BaseBean;
-public interface TaskUtils {
+@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "_class")
+public class CommandArgs implements BaseBean {
- TaskType getType();
+ private static final long serialVersionUID = -85050010490462751L;
- <T extends Task<T>> T newTask();
-
- <T extends TaskTO> T newTaskTO();
-
- <T extends Task<T>> Class<T> taskClass();
-
- <T extends TaskTO> Class<T> taskTOClass();
}
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/command/CommandOutput.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/command/CommandOutput.java
new file mode 100644
index 0000000000..896833a0c3
--- /dev/null
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/command/CommandOutput.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.common.lib.command;
+
+public class CommandOutput extends CommandTO {
+
+ private static final long serialVersionUID = 7711356516501958110L;
+
+ public static class Builder extends CommandTO.Builder {
+
+ public Builder(final String key) {
+ super(key);
+ }
+
+ public Builder(final CommandTO commandTO) {
+ super(commandTO.getKey());
+ args(commandTO.getArgs());
+ }
+
+ @Override
+ protected CommandOutput newInstance() {
+ return new CommandOutput();
+ }
+
+ @Override
+ public Builder args(final CommandArgs args) {
+ return (Builder) super.args(args);
+ }
+
+ public Builder output(final String output) {
+ ((CommandOutput) getInstance()).setOutput(output);
+ return this;
+ }
+
+ @Override
+ public CommandOutput build() {
+ return (CommandOutput) super.build();
+ }
+ }
+
+ private String output;
+
+ public String getOutput() {
+ return output;
+ }
+
+ public void setOutput(final String output) {
+ this.output = output;
+ }
+}
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/command/CommandTO.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/command/CommandTO.java
new file mode 100644
index 0000000000..c9bd8d1206
--- /dev/null
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/command/CommandTO.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.common.lib.command;
+
+import javax.ws.rs.PathParam;
+import org.apache.syncope.common.lib.BaseBean;
+
+public class CommandTO implements BaseBean {
+
+ private static final long serialVersionUID = 7711356516501958110L;
+
+ public static class Builder {
+
+ protected CommandTO instance;
+
+ public Builder(final String key) {
+ getInstance().setKey(key);
+ }
+
+ protected CommandTO newInstance() {
+ return new CommandTO();
+ }
+
+ protected final CommandTO getInstance() {
+ if (instance == null) {
+ instance = newInstance();
+ }
+ return instance;
+ }
+
+ public Builder args(final CommandArgs args) {
+ getInstance().setArgs(args);
+ return this;
+ }
+
+ public CommandTO build() {
+ return getInstance();
+ }
+ }
+
+ private String key;
+
+ private CommandArgs args;
+
+ public String getKey() {
+ return key;
+ }
+
+ @PathParam("key")
+ public void setKey(final String key) {
+ this.key = key;
+ }
+
+ public CommandArgs getArgs() {
+ return args;
+ }
+
+ public void setArgs(final CommandArgs args) {
+ this.args = args;
+ }
+}
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/MacroTaskTO.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/MacroTaskTO.java
new file mode 100644
index 0000000000..01bf44eb6f
--- /dev/null
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/MacroTaskTO.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.common.lib.to;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.syncope.common.lib.command.CommandTO;
+
+@Schema(allOf = { SchedTaskTO.class }, discriminatorProperty = "_class")
+public class MacroTaskTO extends SchedTaskTO {
+
+ private static final long serialVersionUID = -2387363212408909094L;
+
+ private String realm;
+
+ private final List<CommandTO> commands = new ArrayList<>();
+
+ private boolean continueOnError;
+
+ private boolean saveExecs = true;
+
+ @JacksonXmlProperty(localName = "_class", isAttribute = true)
+ @JsonProperty("_class")
+ @Schema(name = "_class", required = true, example = "org.apache.syncope.common.lib.to.MacroTaskTO")
+ @Override
+ public String getDiscriminator() {
+ return getClass().getName();
+ }
+
+ public String getRealm() {
+ return realm;
+ }
+
+ public void setRealm(final String realm) {
+ this.realm = realm;
+ }
+
+ @JacksonXmlElementWrapper(localName = "commands")
+ @JacksonXmlProperty(localName = "command")
+ public List<CommandTO> getCommands() {
+ return commands;
+ }
+
+ public boolean isContinueOnError() {
+ return continueOnError;
+ }
+
+ public void setContinueOnError(final boolean continueOnError) {
+ this.continueOnError = continueOnError;
+ }
+
+ public boolean isSaveExecs() {
+ return saveExecs;
+ }
+
+ public void setSaveExecs(final boolean saveExecs) {
+ this.saveExecs = saveExecs;
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder().
+ appendSuper(super.hashCode()).
+ append(realm).
+ append(commands).
+ append(continueOnError).
+ append(saveExecs).
+ build();
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final MacroTaskTO other = (MacroTaskTO) obj;
+ return new EqualsBuilder().
+ appendSuper(super.equals(obj)).
+ append(realm, other.realm).
+ append(commands, other.commands).
+ append(continueOnError, other.continueOnError).
+ append(saveExecs, other.saveExecs).
+ build();
+ }
+}
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/SchedTaskTO.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/SchedTaskTO.java
index 49a854955d..054d6531dd 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/SchedTaskTO.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/SchedTaskTO.java
@@ -25,7 +25,9 @@ import java.time.OffsetDateTime;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
-@Schema(allOf = { TaskTO.class }, subTypes = { ProvisioningTaskTO.class }, discriminatorProperty = "_class")
+@Schema(allOf = { TaskTO.class },
+ subTypes = { ProvisioningTaskTO.class, MacroTaskTO.class },
+ discriminatorProperty = "_class")
public class SchedTaskTO extends TaskTO implements NamedEntityTO {
private static final long serialVersionUID = -5722284116974636425L;
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
index 8dc10d55f6..555488be6f 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
@@ -22,7 +22,6 @@ import javax.ws.rs.core.Response;
public enum ClientExceptionType {
- AssociatedAnys(Response.Status.BAD_REQUEST),
AssociatedResources(Response.Status.BAD_REQUEST),
Composite(Response.Status.BAD_REQUEST),
ConcurrentModification(Response.Status.PRECONDITION_FAILED),
@@ -70,6 +69,7 @@ public enum ClientExceptionType {
InvalidRequest(Response.Status.BAD_REQUEST),
InvalidValues(Response.Status.BAD_REQUEST),
NotFound(Response.Status.NOT_FOUND),
+ RealmContains(Response.Status.BAD_REQUEST),
RequiredValuesMissing(Response.Status.BAD_REQUEST),
RESTValidation(Response.Status.BAD_REQUEST),
GroupOwnership(Response.Status.BAD_REQUEST),
@@ -77,6 +77,7 @@ public enum ClientExceptionType {
Scheduling(Response.Status.BAD_REQUEST),
DelegatedAdministration(Response.Status.FORBIDDEN),
Reconciliation(Response.Status.BAD_REQUEST),
+ RunError(Response.Status.INTERNAL_SERVER_ERROR),
Unknown(Response.Status.BAD_REQUEST),
Workflow(Response.Status.BAD_REQUEST);
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/IdRepoEntitlement.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/IdRepoEntitlement.java
index 3fe99d4526..ed84d42e6d 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/IdRepoEntitlement.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/IdRepoEntitlement.java
@@ -240,6 +240,8 @@ public final class IdRepoEntitlement {
public static final String DELEGATION_DELETE = "DELEGATION_DELETE";
+ public static final String COMMAND_RUN = "COMMAND_RUN";
+
public static final String LOGGER_LIST = "LOGGER_LIST";
public static final String LOGGER_UPDATE = "LOGGER_UPDATE";
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/IdRepoImplementationType.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/IdRepoImplementationType.java
index 5ffaabf9d0..21df4a1b7e 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/IdRepoImplementationType.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/IdRepoImplementationType.java
@@ -37,6 +37,8 @@ public final class IdRepoImplementationType {
public static final String VALIDATOR = "VALIDATOR";
+ public static final String COMMAND = "COMMAND";
+
public static final String RECIPIENTS_PROVIDER = "RECIPIENTS_PROVIDER";
public static final String AUDIT_APPENDER = "AUDIT_APPENDER";
@@ -49,8 +51,9 @@ public final class IdRepoImplementationType {
Pair.of(ACCOUNT_RULE, "org.apache.syncope.core.persistence.api.dao.AccountRule"),
Pair.of(PASSWORD_RULE, "org.apache.syncope.core.persistence.api.dao.PasswordRule"),
Pair.of(TASKJOB_DELEGATE, "org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate"),
- Pair.of(LOGIC_ACTIONS, "org.apache.syncope.core.provisioning.api.LogicActions"),
+ Pair.of(LOGIC_ACTIONS, "org.apache.syncope.core.logic.api.LogicActions"),
Pair.of(VALIDATOR, "org.apache.syncope.core.persistence.api.attrvalue.validation.PlainAttrValueValidator"),
+ Pair.of(COMMAND, "org.apache.syncope.core.logic.api.Command"),
Pair.of(RECIPIENTS_PROVIDER, "org.apache.syncope.core.provisioning.api.notification.RecipientsProvider"),
Pair.of(AUDIT_APPENDER, "org.apache.syncope.core.logic.audit.AuditAppender"),
Pair.of(ITEM_TRANSFORMER, "org.apache.syncope.core.provisioning.api.data.ItemTransformer"));
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/TaskType.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/TaskType.java
index 97d79df00a..2fc7efd8b5 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/TaskType.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/TaskType.java
@@ -18,6 +18,7 @@
*/
package org.apache.syncope.common.lib.types;
+import org.apache.syncope.common.lib.to.MacroTaskTO;
import org.apache.syncope.common.lib.to.NotificationTaskTO;
import org.apache.syncope.common.lib.to.PropagationTaskTO;
import org.apache.syncope.common.lib.to.PullTaskTO;
@@ -31,7 +32,8 @@ public enum TaskType {
NOTIFICATION(NotificationTaskTO.class),
SCHEDULED(SchedTaskTO.class),
PULL(PullTaskTO.class),
- PUSH(PushTaskTO.class);
+ PUSH(PushTaskTO.class),
+ MACRO(MacroTaskTO.class);
private final Class<? extends TaskTO> toClass;
@@ -52,6 +54,8 @@ public enum TaskType {
? TaskType.NOTIFICATION
: PropagationTaskTO.class.isAssignableFrom(clazz)
? TaskType.PROPAGATION
+ : MacroTaskTO.class.isAssignableFrom(clazz)
+ ? TaskType.MACRO
: TaskType.SCHEDULED;
}
}
diff --git a/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/CommandQuery.java b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/CommandQuery.java
new file mode 100644
index 0000000000..a588b3d2a0
--- /dev/null
+++ b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/CommandQuery.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.common.rest.api.beans;
+
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import javax.ws.rs.QueryParam;
+import org.apache.syncope.common.rest.api.service.JAXRSService;
+
+public class CommandQuery extends AbstractQuery {
+
+ private static final long serialVersionUID = -8792519310029596796L;
+
+ public static class Builder extends AbstractQuery.Builder<CommandQuery, Builder> {
+
+ @Override
+ protected CommandQuery newInstance() {
+ return new CommandQuery();
+ }
+
+ public Builder keyword(final String keyword) {
+ getInstance().setKeyword(keyword);
+ return this;
+ }
+ }
+
+ private String keyword;
+
+ @Parameter(name = JAXRSService.PARAM_KEYWORD, description = "keyword to match", schema =
+ @Schema(implementation = String.class))
+ public String getKeyword() {
+ return keyword;
+ }
+
+ @QueryParam(JAXRSService.PARAM_KEYWORD)
+ public void setKeyword(final String keyword) {
+ this.keyword = keyword;
+ }
+}
diff --git a/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/CommandService.java b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/CommandService.java
new file mode 100644
index 0000000000..6fbef8a7b7
--- /dev/null
+++ b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/CommandService.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.common.rest.api.service;
+
+import io.swagger.v3.oas.annotations.security.SecurityRequirement;
+import io.swagger.v3.oas.annotations.security.SecurityRequirements;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import javax.ws.rs.BeanParam;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import org.apache.syncope.common.lib.command.CommandOutput;
+import org.apache.syncope.common.lib.command.CommandTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.beans.CommandQuery;
+
+/**
+ * REST operations for commands.
+ */
+@Tag(name = "Commands")
+@SecurityRequirements({
+ @SecurityRequirement(name = "BasicAuthentication"),
+ @SecurityRequirement(name = "Bearer") })
+@Path("commands")
+public interface CommandService extends JAXRSService {
+
+ /**
+ * Returns a paged list of all commands.
+ *
+ * @param query query conditions
+ * @return list of all commands.
+ */
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ PagedResult<CommandTO> search(@BeanParam CommandQuery query);
+
+ /**
+ * Returns the command for the given key, if found.
+ *
+ * @param key command key
+ * @return the command for the given key, if found
+ */
+ @GET
+ @Path("{key}")
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ CommandTO read(@PathParam("key") String key);
+
+ /**
+ * Runs the given command with the given arguments and returns the resulting output.
+ *
+ * @param command command to run, with arguments
+ * @return command output
+ */
+ @POST
+ @Path("{key}")
+ @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ CommandOutput run(CommandTO command);
+}
diff --git a/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/JAXRSService.java b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/JAXRSService.java
index 51a59cc576..a947ddbe71 100644
--- a/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/JAXRSService.java
+++ b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/JAXRSService.java
@@ -28,6 +28,8 @@ public interface JAXRSService {
String PARAM_ORDERBY = "orderby";
+ String PARAM_KEYWORD = "keyword";
+
String PARAM_RESOURCE = "resource";
String PARAM_NOTIFICATION = "notification";
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
index 813c7e7301..d0776080a3 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
@@ -33,13 +33,13 @@ import org.apache.syncope.common.lib.to.AnyTO;
import org.apache.syncope.common.lib.to.PropagationStatus;
import org.apache.syncope.common.lib.to.ProvisioningResult;
import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.core.logic.api.LogicActions;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
import org.apache.syncope.core.persistence.api.dao.RealmDAO;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
import org.apache.syncope.core.persistence.api.entity.AnyType;
import org.apache.syncope.core.persistence.api.entity.Realm;
-import org.apache.syncope.core.provisioning.api.LogicActions;
import org.apache.syncope.core.provisioning.java.utils.TemplateUtils;
import org.apache.syncope.core.spring.implementation.ImplementationManager;
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
index 509821e117..cfcae26dd8 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
@@ -40,6 +40,7 @@ import org.apache.syncope.common.lib.types.AnyEntitlement;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.PatchOperation;
+import org.apache.syncope.core.logic.api.LogicActions;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
@@ -51,7 +52,6 @@ import org.apache.syncope.core.persistence.api.entity.AnyType;
import org.apache.syncope.core.persistence.api.entity.Realm;
import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
-import org.apache.syncope.core.provisioning.api.LogicActions;
import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder;
import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
import org.apache.syncope.core.provisioning.java.utils.TemplateUtils;
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/CommandLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/CommandLogic.java
new file mode 100644
index 0000000000..907a343e12
--- /dev/null
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/CommandLogic.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.logic;
+
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.command.CommandArgs;
+import org.apache.syncope.common.lib.command.CommandTO;
+import org.apache.syncope.common.lib.to.EntityTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.IdRepoEntitlement;
+import org.apache.syncope.common.lib.types.IdRepoImplementationType;
+import org.apache.syncope.core.logic.api.Command;
+import org.apache.syncope.core.persistence.api.dao.ImplementationDAO;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.entity.Implementation;
+import org.apache.syncope.core.spring.implementation.ImplementationManager;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.transaction.annotation.Transactional;
+
+public class CommandLogic extends AbstractLogic<EntityTO> {
+
+ protected final ImplementationDAO implementationDAO;
+
+ protected final Map<String, Command<?>> perContextCommands = new ConcurrentHashMap<>();
+
+ public CommandLogic(final ImplementationDAO implementationDAO) {
+ this.implementationDAO = implementationDAO;
+ }
+
+ @PreAuthorize("hasRole('" + IdRepoEntitlement.IMPLEMENTATION_LIST + "')")
+ @Transactional(readOnly = true)
+ public Pair<Integer, List<CommandTO>> search(final int page, final int size, final String keyword) {
+ List<Implementation> result = implementationDAO.findByTypeAndKeyword(IdRepoImplementationType.COMMAND, keyword);
+
+ int count = result.size();
+
+ List<CommandTO> commands = result.stream().
+ skip((page - 1) * size).
+ limit(size).
+ map(command -> {
+ try {
+ return new CommandTO.Builder(command.getKey()).
+ args(ImplementationManager.emptyArgs(command)).build();
+ } catch (Exception e) {
+ LOG.error("Could not get arg class for {}", command, e);
+ return null;
+ }
+ }).
+ filter(Objects::nonNull).
+ collect(Collectors.toList());
+
+ return Pair.of(count, commands);
+ }
+
+ @PreAuthorize("hasRole('" + IdRepoEntitlement.IMPLEMENTATION_READ + "')")
+ @Transactional(readOnly = true)
+ public CommandTO read(final String key) {
+ Implementation impl = Optional.ofNullable(implementationDAO.find(key)).
+ orElseThrow(() -> new NotFoundException("Implementation " + key));
+
+ try {
+ return new CommandTO.Builder(impl.getKey()).
+ args(ImplementationManager.emptyArgs(impl)).build();
+ } catch (Exception e) {
+ SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidImplementation);
+ sce.getElements().add("Could not build " + impl.getKey());
+ throw sce;
+ }
+ }
+
+ @PreAuthorize("hasRole('" + IdRepoEntitlement.COMMAND_RUN + "')")
+ @SuppressWarnings("unchecked")
+ public String run(final CommandTO command) {
+ Implementation impl = Optional.ofNullable(implementationDAO.find(command.getKey())).
+ orElseThrow(() -> new NotFoundException("Implementation " + command.getKey()));
+
+ Command<CommandArgs> runnable;
+ try {
+ runnable = (Command<CommandArgs>) ImplementationManager.build(
+ impl,
+ () -> perContextCommands.get(impl.getKey()),
+ instance -> perContextCommands.put(impl.getKey(), instance));
+ } catch (Exception e) {
+ SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidImplementation);
+ sce.getElements().add("Could not build " + impl.getKey());
+ throw sce;
+ }
+
+ try {
+ return runnable.run(command.getArgs());
+ } catch (Exception e) {
+ LOG.error("While running {} on {}", command.getKey(), command.getArgs(), e);
+
+ SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.RunError);
+ sce.getElements().add(e.getMessage());
+ throw sce;
+ }
+ }
+
+ @Override
+ protected EntityTO resolveReference(final Method method, final Object... args)
+ throws UnresolvedReferenceException {
+
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
index 4891d5f0d4..52410edd51 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
@@ -45,6 +45,7 @@ import org.apache.syncope.common.lib.types.ImplementationEngine;
import org.apache.syncope.common.lib.types.JobType;
import org.apache.syncope.common.lib.types.PatchOperation;
import org.apache.syncope.common.lib.types.ProvisionAction;
+import org.apache.syncope.core.logic.api.LogicActions;
import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
import org.apache.syncope.core.persistence.api.dao.GroupDAO;
@@ -61,7 +62,6 @@ import org.apache.syncope.core.persistence.api.entity.Realm;
import org.apache.syncope.core.persistence.api.entity.group.Group;
import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
import org.apache.syncope.core.provisioning.api.GroupProvisioningManager;
-import org.apache.syncope.core.provisioning.api.LogicActions;
import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
import org.apache.syncope.core.provisioning.api.data.TaskDataBinder;
import org.apache.syncope.core.provisioning.api.job.JobManager;
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/IdRepoLogicContext.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/IdRepoLogicContext.java
index 1c38c68d3e..9a4e62889a 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/IdRepoLogicContext.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/IdRepoLogicContext.java
@@ -34,6 +34,7 @@ import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
import org.apache.syncope.core.persistence.api.dao.ApplicationDAO;
import org.apache.syncope.core.persistence.api.dao.AuditConfDAO;
+import org.apache.syncope.core.persistence.api.dao.CASSPClientAppDAO;
import org.apache.syncope.core.persistence.api.dao.DelegationDAO;
import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
import org.apache.syncope.core.persistence.api.dao.DynRealmDAO;
@@ -43,6 +44,7 @@ import org.apache.syncope.core.persistence.api.dao.GroupDAO;
import org.apache.syncope.core.persistence.api.dao.ImplementationDAO;
import org.apache.syncope.core.persistence.api.dao.MailTemplateDAO;
import org.apache.syncope.core.persistence.api.dao.NotificationDAO;
+import org.apache.syncope.core.persistence.api.dao.OIDCRPClientAppDAO;
import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
import org.apache.syncope.core.persistence.api.dao.RealmDAO;
@@ -51,6 +53,7 @@ import org.apache.syncope.core.persistence.api.dao.ReportDAO;
import org.apache.syncope.core.persistence.api.dao.ReportExecDAO;
import org.apache.syncope.core.persistence.api.dao.ReportTemplateDAO;
import org.apache.syncope.core.persistence.api.dao.RoleDAO;
+import org.apache.syncope.core.persistence.api.dao.SAML2SPClientAppDAO;
import org.apache.syncope.core.persistence.api.dao.SecurityQuestionDAO;
import org.apache.syncope.core.persistence.api.dao.TaskDAO;
import org.apache.syncope.core.persistence.api.dao.TaskExecDAO;
@@ -233,6 +236,12 @@ public class IdRepoLogicContext {
auditManager);
}
+ @ConditionalOnMissingBean
+ @Bean
+ public CommandLogic commandLogic(final ImplementationDAO implementationDAO) {
+ return new CommandLogic(implementationDAO);
+ }
+
@ConditionalOnMissingBean
@Bean
public FIQLQueryLogic fiqlQueryLogic(
@@ -363,10 +372,23 @@ public class IdRepoLogicContext {
final RealmDataBinder binder,
final RealmDAO realmDAO,
final AnySearchDAO anySearchDAO,
+ final TaskDAO taskDAO,
+ final CASSPClientAppDAO casSPClientAppDAO,
+ final OIDCRPClientAppDAO oidcRPClientAppDAO,
+ final SAML2SPClientAppDAO saml2SPClientAppDAO,
final PropagationManager propagationManager,
final PropagationTaskExecutor taskExecutor) {
- return new RealmLogic(realmDAO, anySearchDAO, binder, propagationManager, taskExecutor);
+ return new RealmLogic(
+ realmDAO,
+ anySearchDAO,
+ taskDAO,
+ casSPClientAppDAO,
+ oidcRPClientAppDAO,
+ saml2SPClientAppDAO,
+ binder,
+ propagationManager,
+ taskExecutor);
}
@ConditionalOnMissingBean
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ImplementationLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ImplementationLogic.java
index 487bb94c42..09853e398f 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ImplementationLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ImplementationLogic.java
@@ -197,6 +197,10 @@ public class ImplementationLogic extends AbstractTransactionalLogic<Implementati
inUse = !taskDAO.findByDelegate(implementation).isEmpty();
break;
+ case IdRepoImplementationType.COMMAND:
+ inUse = !taskDAO.findByCommand(implementation).isEmpty();
+ break;
+
case IdMImplementationType.RECON_FILTER_BUILDER:
inUse = !taskDAO.findByReconFilterBuilder(implementation).isEmpty();
break;
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RealmLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RealmLogic.java
index 966f9abb78..cce7a068fc 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RealmLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RealmLogic.java
@@ -36,9 +36,13 @@ import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.IdRepoEntitlement;
import org.apache.syncope.common.lib.types.ResourceOperation;
import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.CASSPClientAppDAO;
import org.apache.syncope.core.persistence.api.dao.DuplicateException;
import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.dao.OIDCRPClientAppDAO;
import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.SAML2SPClientAppDAO;
+import org.apache.syncope.core.persistence.api.dao.TaskDAO;
import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
import org.apache.syncope.core.persistence.api.dao.search.AttrCond;
import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
@@ -60,6 +64,14 @@ public class RealmLogic extends AbstractTransactionalLogic<RealmTO> {
protected final AnySearchDAO searchDAO;
+ protected final TaskDAO taskDAO;
+
+ protected final CASSPClientAppDAO casSPClientAppDAO;
+
+ protected final OIDCRPClientAppDAO oidcRPClientAppDAO;
+
+ protected final SAML2SPClientAppDAO saml2SPClientAppDAO;
+
protected final RealmDataBinder binder;
protected final PropagationManager propagationManager;
@@ -69,12 +81,20 @@ public class RealmLogic extends AbstractTransactionalLogic<RealmTO> {
public RealmLogic(
final RealmDAO realmDAO,
final AnySearchDAO searchDAO,
+ final TaskDAO taskDAO,
+ final CASSPClientAppDAO casSPClientAppDAO,
+ final OIDCRPClientAppDAO oidcRPClientAppDAO,
+ final SAML2SPClientAppDAO saml2SPClientAppDAO,
final RealmDataBinder binder,
final PropagationManager propagationManager,
final PropagationTaskExecutor taskExecutor) {
this.realmDAO = realmDAO;
this.searchDAO = searchDAO;
+ this.taskDAO = taskDAO;
+ this.casSPClientAppDAO = casSPClientAppDAO;
+ this.oidcRPClientAppDAO = oidcRPClientAppDAO;
+ this.saml2SPClientAppDAO = saml2SPClientAppDAO;
this.binder = binder;
this.propagationManager = propagationManager;
this.taskExecutor = taskExecutor;
@@ -212,14 +232,21 @@ public class RealmLogic extends AbstractTransactionalLogic<RealmTO> {
int users = searchDAO.count(realm, true, adminRealms, allMatchingCond, AnyTypeKind.USER);
int groups = searchDAO.count(realm, true, adminRealms, allMatchingCond, AnyTypeKind.GROUP);
int anyObjects = searchDAO.count(realm, true, adminRealms, allMatchingCond, AnyTypeKind.ANY_OBJECT);
-
- if (users + groups + anyObjects > 0) {
- SyncopeClientException containedAnys = SyncopeClientException.build(ClientExceptionType.AssociatedAnys);
- containedAnys.getElements().add(users + " user(s)");
- containedAnys.getElements().add(groups + " group(s)");
- containedAnys.getElements().add(anyObjects + " anyObject(s)");
- throw containedAnys;
+ int macroTasks = taskDAO.findByRealm(realm).size();
+ int clientApps = casSPClientAppDAO.findByRealm(realm).size()
+ + saml2SPClientAppDAO.findByRealm(realm).size()
+ + oidcRPClientAppDAO.findByRealm(realm).size();
+
+ if (users + groups + anyObjects + macroTasks + clientApps > 0) {
+ SyncopeClientException realmContains = SyncopeClientException.build(ClientExceptionType.RealmContains);
+ realmContains.getElements().add(users + " user(s)");
+ realmContains.getElements().add(groups + " group(s)");
+ realmContains.getElements().add(anyObjects + " anyObject(s)");
+ realmContains.getElements().add(macroTasks + " command task(s)");
+ realmContains.getElements().add(clientApps + " client app(s)");
+ throw realmContains;
}
+
PropagationByResource<String> propByRes = new PropagationByResource<>();
propByRes.addAll(ResourceOperation.DELETE, realm.getResourceKeys());
List<PropagationTaskInfo> taskInfos = propagationManager.createTasks(realm, propByRes, null);
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
index 91a1d4932c..9eb7051e5f 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
@@ -25,6 +25,7 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
+import java.util.Set;
import java.util.stream.Collectors;
import javax.ws.rs.core.Response;
import org.apache.commons.lang3.ArrayUtils;
@@ -34,6 +35,7 @@ import org.apache.syncope.common.keymaster.client.api.ConfParamOps;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.to.ExecTO;
import org.apache.syncope.common.lib.to.JobTO;
+import org.apache.syncope.common.lib.to.MacroTaskTO;
import org.apache.syncope.common.lib.to.PropagationTaskTO;
import org.apache.syncope.common.lib.to.SchedTaskTO;
import org.apache.syncope.common.lib.to.TaskTO;
@@ -52,6 +54,9 @@ import org.apache.syncope.core.persistence.api.dao.NotificationDAO;
import org.apache.syncope.core.persistence.api.dao.TaskDAO;
import org.apache.syncope.core.persistence.api.dao.TaskExecDAO;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.Notification;
+import org.apache.syncope.core.persistence.api.entity.task.MacroTask;
import org.apache.syncope.core.persistence.api.entity.task.NotificationTask;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
@@ -69,6 +74,7 @@ import org.apache.syncope.core.provisioning.api.utils.ExceptionUtils2;
import org.apache.syncope.core.provisioning.java.job.TaskJob;
import org.apache.syncope.core.provisioning.java.propagation.DefaultPropagationReporter;
import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
import org.identityconnectors.framework.common.objects.ObjectClass;
import org.quartz.JobDataMap;
import org.quartz.JobKey;
@@ -124,6 +130,13 @@ public class TaskLogic extends AbstractExecutableLogic<TaskTO> {
this.taskUtilsFactory = taskUtilsFactory;
}
+ protected void securityChecks(final String entitlement, final String realm) {
+ Set<String> authRealms = AuthContextUtils.getAuthorizations().get(entitlement);
+ if (authRealms.stream().noneMatch(r -> realm.startsWith(r))) {
+ throw new DelegatedAdministrationException(realm, MacroTask.class.getSimpleName(), null);
+ }
+ }
+
@PreAuthorize("hasRole('" + IdRepoEntitlement.TASK_CREATE + "')")
public <T extends SchedTaskTO> T createSchedTask(final TaskType type, final T taskTO) {
TaskUtils taskUtils = taskUtilsFactory.getInstance(taskTO);
@@ -132,6 +145,11 @@ public class TaskLogic extends AbstractExecutableLogic<TaskTO> {
sce.getElements().add("Found " + type + ", expected " + taskUtils.getType());
throw sce;
}
+
+ if (taskUtils.getType() == TaskType.MACRO) {
+ securityChecks(IdRepoEntitlement.TASK_CREATE, ((MacroTaskTO) taskTO).getRealm());
+ }
+
SchedTask task = binder.createSchedTask(taskTO, taskUtils);
task = taskDAO.save(task);
@@ -166,6 +184,11 @@ public class TaskLogic extends AbstractExecutableLogic<TaskTO> {
throw sce;
}
+ if (taskUtils.getType() == TaskType.MACRO) {
+ securityChecks(IdRepoEntitlement.TASK_UPDATE, ((MacroTask) task).getRealm().getFullPath());
+ securityChecks(IdRepoEntitlement.TASK_UPDATE, ((MacroTaskTO) taskTO).getRealm());
+ }
+
binder.updateSchedTask(task, taskTO, taskUtils);
task = taskDAO.save(task);
try {
@@ -187,7 +210,6 @@ public class TaskLogic extends AbstractExecutableLogic<TaskTO> {
@PreAuthorize("hasRole('" + IdRepoEntitlement.TASK_LIST + "')")
@Transactional(readOnly = true)
- @SuppressWarnings("unchecked")
public <T extends TaskTO> Pair<Integer, List<T>> search(
final TaskType type,
final String resource,
@@ -204,12 +226,32 @@ public class TaskLogic extends AbstractExecutableLogic<TaskTO> {
throw new IllegalArgumentException("type is required");
}
+ ExternalResource resourceObj = resourceDAO.find(resource);
+ if (resource != null && resourceObj == null) {
+ throw new IllegalArgumentException("Missing External Resource: " + resource);
+ }
+
+ Notification notificationObj = notificationDAO.find(notification);
+ if (notification != null && notificationObj == null) {
+ throw new IllegalArgumentException("Missing Notification: " + notification);
+ }
+
int count = taskDAO.count(
- type, resourceDAO.find(resource), notificationDAO.find(notification), anyTypeKind, entityKey);
+ type,
+ resourceObj,
+ notificationObj,
+ anyTypeKind,
+ entityKey);
List<T> result = taskDAO.findAll(
- type, resourceDAO.find(resource), notificationDAO.find(notification), anyTypeKind, entityKey,
- page, size, orderByClauses).stream().
+ type,
+ resourceObj,
+ notificationObj,
+ anyTypeKind,
+ entityKey,
+ page,
+ size,
+ orderByClauses).stream().
<T>map(task -> binder.getTaskTO(task, taskUtilsFactory.getInstance(type), details)).
collect(Collectors.toList());
@@ -236,6 +278,10 @@ public class TaskLogic extends AbstractExecutableLogic<TaskTO> {
throw sce;
}
+ if (taskUtils.getType() == TaskType.MACRO) {
+ securityChecks(IdRepoEntitlement.TASK_READ, ((MacroTask) task).getRealm().getFullPath());
+ }
+
return binder.getTaskTO(task, taskUtilsFactory.getInstance(task), details);
}
@@ -249,11 +295,11 @@ public class TaskLogic extends AbstractExecutableLogic<TaskTO> {
throw sce;
}
- TaskUtils taskUtil = taskUtilsFactory.getInstance(task);
+ TaskUtils taskUtils = taskUtilsFactory.getInstance(task);
String executor = AuthContextUtils.getUsername();
ExecTO result = null;
- switch (taskUtil.getType()) {
+ switch (taskUtils.getType()) {
case PROPAGATION:
PropagationTask propagationTask = (PropagationTask) task;
PropagationTaskInfo taskInfo = new PropagationTaskInfo(
@@ -281,6 +327,11 @@ public class TaskLogic extends AbstractExecutableLogic<TaskTO> {
case SCHEDULED:
case PULL:
case PUSH:
+ case MACRO:
+ if (taskUtils.getType() == TaskType.MACRO) {
+ securityChecks(IdRepoEntitlement.TASK_EXECUTE, ((MacroTask) task).getRealm().getFullPath());
+ }
+
if (!((SchedTask) task).isActive()) {
SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Scheduling);
sce.getElements().add("Task " + key + " is not active");
@@ -337,6 +388,10 @@ public class TaskLogic extends AbstractExecutableLogic<TaskTO> {
throw sce;
}
+ if (taskUtils.getType() == TaskType.MACRO) {
+ securityChecks(IdRepoEntitlement.TASK_DELETE, ((MacroTask) task).getRealm().getFullPath());
+ }
+
T taskToDelete = binder.getTaskTO(task, taskUtils, true);
if (TaskType.SCHEDULED == taskUtils.getType()
@@ -357,10 +412,14 @@ public class TaskLogic extends AbstractExecutableLogic<TaskTO> {
Task<?> task = taskDAO.find(key).orElseThrow(() -> new NotFoundException("Task " + key));
+ if (task instanceof MacroTask) {
+ securityChecks(IdRepoEntitlement.TASK_READ, ((MacroTask) task).getRealm().getFullPath());
+ }
+
Integer count = taskExecDAO.count(task);
List<ExecTO> result = taskExecDAO.findAll(task, page, size, orderByClauses).stream().
- map(taskExec -> binder.getExecTO(taskExec)).collect(Collectors.toList());
+ map(exec -> binder.getExecTO(exec)).collect(Collectors.toList());
return Pair.of(count, result);
}
@@ -369,18 +428,36 @@ public class TaskLogic extends AbstractExecutableLogic<TaskTO> {
@Override
public List<ExecTO> listRecentExecutions(final int max) {
return taskExecDAO.findRecent(max).stream().
- map(taskExec -> binder.getExecTO(taskExec)).collect(Collectors.toList());
+ map(exec -> {
+ try {
+ if (exec.getTask() instanceof MacroTask) {
+ securityChecks(IdRepoEntitlement.TASK_DELETE,
+ ((MacroTask) exec.getTask()).getRealm().getFullPath());
+ }
+
+ return binder.getExecTO(exec);
+ } catch (DelegatedAdministrationException e) {
+ LOG.error("Skip executions for command task", e);
+ return null;
+ }
+ }).
+ filter(Objects::nonNull).
+ collect(Collectors.toList());
}
@PreAuthorize("hasRole('" + IdRepoEntitlement.TASK_DELETE + "')")
@Override
public ExecTO deleteExecution(final String execKey) {
- TaskExec<?> taskExec = taskExecDAO.find(execKey).
+ TaskExec<?> exec = taskExecDAO.find(execKey).
orElseThrow(() -> new NotFoundException("Task execution " + execKey));
- ExecTO taskExecutionToDelete = binder.getExecTO(taskExec);
- taskExecDAO.delete(taskExec);
- return taskExecutionToDelete;
+ if (exec.getTask() instanceof MacroTask) {
+ securityChecks(IdRepoEntitlement.TASK_DELETE, ((MacroTask) exec.getTask()).getRealm().getFullPath());
+ }
+
+ ExecTO executionToDelete = binder.getExecTO(exec);
+ taskExecDAO.delete(exec);
+ return executionToDelete;
}
@PreAuthorize("hasRole('" + IdRepoEntitlement.TASK_DELETE + "')")
@@ -402,6 +479,11 @@ public class TaskLogic extends AbstractExecutableLogic<TaskTO> {
batchResponseItems.add(item);
try {
+ if (exec.getTask() instanceof MacroTask) {
+ securityChecks(IdRepoEntitlement.TASK_DELETE,
+ ((MacroTask) exec.getTask()).getRealm().getFullPath());
+ }
+
taskExecDAO.delete(exec);
item.setStatus(Response.Status.OK.getStatusCode());
} catch (Exception e) {
@@ -435,6 +517,10 @@ public class TaskLogic extends AbstractExecutableLogic<TaskTO> {
public JobTO getJob(final String key) {
Task<?> task = taskDAO.find(key).orElseThrow(() -> new NotFoundException("Task " + key));
+ if (task instanceof MacroTask) {
+ securityChecks(IdRepoEntitlement.TASK_READ, ((MacroTask) task).getRealm().getFullPath());
+ }
+
JobTO jobTO = null;
try {
jobTO = getJobTO(JobNamer.getJobKey(task), false);
@@ -456,6 +542,10 @@ public class TaskLogic extends AbstractExecutableLogic<TaskTO> {
public void actionJob(final String key, final JobAction action) {
Task<?> task = taskDAO.find(key).orElseThrow(() -> new NotFoundException("Task " + key));
+ if (task instanceof MacroTask) {
+ securityChecks(IdRepoEntitlement.TASK_EXECUTE, ((MacroTask) task).getRealm().getFullPath());
+ }
+
doActionJob(JobNamer.getJobKey(task), action);
}
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
index 28fc62443d..023d5e21fc 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
@@ -45,6 +45,7 @@ import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.IdRepoEntitlement;
import org.apache.syncope.common.lib.types.PatchOperation;
+import org.apache.syncope.core.logic.api.LogicActions;
import org.apache.syncope.core.persistence.api.dao.AccessTokenDAO;
import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
@@ -59,7 +60,6 @@ import org.apache.syncope.core.persistence.api.entity.AccessToken;
import org.apache.syncope.core.persistence.api.entity.Realm;
import org.apache.syncope.core.persistence.api.entity.group.Group;
import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.provisioning.api.LogicActions;
import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/TaskUtils.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/api/Command.java
similarity index 67%
copy from core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/TaskUtils.java
copy to core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/api/Command.java
index e8f5c15d38..88047c89f5 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/TaskUtils.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/api/Command.java
@@ -16,20 +16,12 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.syncope.core.persistence.api.entity.task;
+package org.apache.syncope.core.logic.api;
-import org.apache.syncope.common.lib.to.TaskTO;
-import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.common.lib.command.CommandArgs;
-public interface TaskUtils {
+@FunctionalInterface
+public interface Command<A extends CommandArgs> {
- TaskType getType();
-
- <T extends Task<T>> T newTask();
-
- <T extends TaskTO> T newTaskTO();
-
- <T extends Task<T>> Class<T> taskClass();
-
- <T extends TaskTO> Class<T> taskTOClass();
+ String run(A args);
}
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/LogicActions.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/api/LogicActions.java
similarity index 97%
rename from core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/LogicActions.java
rename to core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/api/LogicActions.java
index 5c5b766a3f..7ace5cef63 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/LogicActions.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/api/LogicActions.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.syncope.core.provisioning.api;
+package org.apache.syncope.core.logic.api;
import java.util.List;
import org.apache.syncope.common.lib.request.AnyCR;
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
index a9e3194667..b1aa633cf8 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
@@ -33,6 +33,8 @@ import org.apache.syncope.common.lib.report.ReportletConf;
import org.apache.syncope.common.lib.types.IdMImplementationType;
import org.apache.syncope.common.lib.types.IdRepoImplementationType;
import org.apache.syncope.common.lib.types.ImplementationTypesHolder;
+import org.apache.syncope.core.logic.api.Command;
+import org.apache.syncope.core.logic.api.LogicActions;
import org.apache.syncope.core.logic.audit.AuditAppender;
import org.apache.syncope.core.logic.audit.JdbcAuditAppender;
import org.apache.syncope.core.persistence.api.ImplementationLookup;
@@ -47,7 +49,6 @@ import org.apache.syncope.core.persistence.api.dao.PushCorrelationRule;
import org.apache.syncope.core.persistence.api.dao.PushCorrelationRuleConfClass;
import org.apache.syncope.core.persistence.api.dao.Reportlet;
import org.apache.syncope.core.persistence.api.dao.ReportletConfClass;
-import org.apache.syncope.core.provisioning.api.LogicActions;
import org.apache.syncope.core.provisioning.api.ProvisionSorter;
import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate;
@@ -243,6 +244,10 @@ public class ClassPathScanImplementationLookup implements ImplementationLookup {
if (ProvisionSorter.class.isAssignableFrom(clazz) && !isAbstractClazz) {
classNames.get(IdMImplementationType.PROVISION_SORTER).add(bd.getBeanClassName());
}
+
+ if (Command.class.isAssignableFrom(clazz) && !isAbstractClazz) {
+ classNames.get(IdRepoImplementationType.COMMAND).add(bd.getBeanClassName());
+ }
} catch (Throwable t) {
LOG.warn("Could not inspect class {}", bd.getBeanClassName(), t);
}
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/job/MacroRunJobDelegate.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/job/MacroRunJobDelegate.java
new file mode 100644
index 0000000000..9dab5397aa
--- /dev/null
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/job/MacroRunJobDelegate.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.logic.job;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import org.apache.syncope.common.lib.command.CommandArgs;
+import org.apache.syncope.core.logic.api.Command;
+import org.apache.syncope.core.persistence.api.dao.ImplementationDAO;
+import org.apache.syncope.core.persistence.api.entity.Implementation;
+import org.apache.syncope.core.persistence.api.entity.task.MacroTask;
+import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
+import org.apache.syncope.core.provisioning.java.job.AbstractSchedTaskJobDelegate;
+import org.apache.syncope.core.spring.implementation.ImplementationManager;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class MacroRunJobDelegate extends AbstractSchedTaskJobDelegate<MacroTask> {
+
+ @Autowired
+ protected ImplementationDAO implementationDAO;
+
+ protected final Map<String, Command<?>> perContextCommands = new ConcurrentHashMap<>();
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected String doExecute(final boolean dryRun, final String executor, final JobExecutionContext context)
+ throws JobExecutionException {
+
+ StringBuilder output = new StringBuilder();
+ for (int i = 0; i < task.getCommands().size(); i++) {
+ Implementation command = task.getCommands().get(i);
+
+ Command<CommandArgs> runnable;
+ try {
+ runnable = (Command<CommandArgs>) ImplementationManager.build(
+ command,
+ () -> perContextCommands.get(command.getKey()),
+ instance -> perContextCommands.put(command.getKey(), instance));
+ } catch (Exception e) {
+ throw new JobExecutionException("Could not build " + command.getKey(), e);
+ }
+
+ String args = POJOHelper.serialize(task.getCommandArgs().get(i));
+
+ output.append("Command[").append(i).append("]: ").
+ append(command.getKey()).append(" ").append(args).append("\n");
+ if (dryRun) {
+ output.append(command).append(' ').append(args);
+ } else {
+ try {
+ output.append(runnable.run(task.getCommandArgs().get(i)));
+ } catch (Exception e) {
+ if (task.isContinueOnError()) {
+ output.append("Continuing on error: <").append(e.getMessage()).append('>');
+ LOG.error("While running {} with args {}, continuing on error",
+ command.getKey(), args, e);
+ } else {
+ throw new RuntimeException("While running " + command.getKey(), e);
+ }
+ }
+ }
+ output.append("\n\n");
+ }
+
+ output.append("COMPLETED");
+ return output.toString();
+ }
+
+ @Override
+ protected boolean hasToBeRegistered(final TaskExec<?> execution) {
+ return task.isSaveExecs();
+ }
+}
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/IdRepoRESTCXFContext.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/IdRepoRESTCXFContext.java
index 398ae2013b..aebfacf737 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/IdRepoRESTCXFContext.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/IdRepoRESTCXFContext.java
@@ -52,6 +52,7 @@ import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
import org.apache.syncope.common.rest.api.service.AnyTypeService;
import org.apache.syncope.common.rest.api.service.ApplicationService;
import org.apache.syncope.common.rest.api.service.AuditService;
+import org.apache.syncope.common.rest.api.service.CommandService;
import org.apache.syncope.common.rest.api.service.DelegationService;
import org.apache.syncope.common.rest.api.service.DynRealmService;
import org.apache.syncope.common.rest.api.service.FIQLQueryService;
@@ -77,6 +78,7 @@ import org.apache.syncope.core.logic.AnyTypeClassLogic;
import org.apache.syncope.core.logic.AnyTypeLogic;
import org.apache.syncope.core.logic.ApplicationLogic;
import org.apache.syncope.core.logic.AuditLogic;
+import org.apache.syncope.core.logic.CommandLogic;
import org.apache.syncope.core.logic.DelegationLogic;
import org.apache.syncope.core.logic.DynRealmLogic;
import org.apache.syncope.core.logic.FIQLQueryLogic;
@@ -108,6 +110,7 @@ import org.apache.syncope.core.rest.cxf.service.AnyTypeClassServiceImpl;
import org.apache.syncope.core.rest.cxf.service.AnyTypeServiceImpl;
import org.apache.syncope.core.rest.cxf.service.ApplicationServiceImpl;
import org.apache.syncope.core.rest.cxf.service.AuditServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.CommandServiceImpl;
import org.apache.syncope.core.rest.cxf.service.DelegationServiceImpl;
import org.apache.syncope.core.rest.cxf.service.DynRealmServiceImpl;
import org.apache.syncope.core.rest.cxf.service.FIQLQueryServiceImpl;
@@ -375,6 +378,12 @@ public class IdRepoRESTCXFContext {
return new AuditServiceImpl(auditLogic);
}
+ @ConditionalOnMissingBean
+ @Bean
+ public CommandService commandService(final CommandLogic commandLogic) {
+ return new CommandServiceImpl(commandLogic);
+ }
+
@ConditionalOnMissingBean
@Bean
public FIQLQueryService fiqlQueryService(final FIQLQueryLogic fiqlQueryLogic) {
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/CommandServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/CommandServiceImpl.java
new file mode 100644
index 0000000000..62c997671f
--- /dev/null
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/CommandServiceImpl.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.rest.cxf.service;
+
+import java.util.List;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.command.CommandOutput;
+import org.apache.syncope.common.lib.command.CommandTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.rest.api.beans.CommandQuery;
+import org.apache.syncope.common.rest.api.service.CommandService;
+import org.apache.syncope.core.logic.CommandLogic;
+import org.springframework.stereotype.Service;
+
+@Service
+public class CommandServiceImpl extends AbstractService implements CommandService {
+
+ protected final CommandLogic logic;
+
+ public CommandServiceImpl(final CommandLogic logic) {
+ this.logic = logic;
+ }
+
+ @Override
+ public PagedResult<CommandTO> search(final CommandQuery query) {
+ String keyword = query.getKeyword() == null ? null : query.getKeyword().replace('*', '%');
+ Pair<Integer, List<CommandTO>> result = logic.search(query.getPage(), query.getSize(), keyword);
+ return buildPagedResult(result.getRight(), query.getPage(), query.getSize(), result.getLeft());
+ }
+
+ @Override
+ public CommandTO read(final String key) {
+ return logic.read(key);
+ }
+
+ @Override
+ public CommandOutput run(final CommandTO command) {
+ return new CommandOutput.Builder(command).output(logic.run(command)).build();
+ }
+}
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ImplementationDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ImplementationDAO.java
index 44b19e9b70..919dffafa1 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ImplementationDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ImplementationDAO.java
@@ -27,6 +27,8 @@ public interface ImplementationDAO extends DAO<Implementation> {
List<Implementation> findByType(String type);
+ List<Implementation> findByTypeAndKeyword(String type, String keyword);
+
List<Implementation> findAll();
Implementation save(Implementation implementation);
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/TaskDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/TaskDAO.java
index 6e03859157..58dd858e96 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/TaskDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/TaskDAO.java
@@ -29,6 +29,8 @@ import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
import org.apache.syncope.core.persistence.api.entity.ExternalResource;
import org.apache.syncope.core.persistence.api.entity.Implementation;
import org.apache.syncope.core.persistence.api.entity.Notification;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.api.entity.task.MacroTask;
import org.apache.syncope.core.persistence.api.entity.task.PullTask;
import org.apache.syncope.core.persistence.api.entity.task.PushTask;
import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
@@ -50,6 +52,10 @@ public interface TaskDAO extends DAO<Task<?>> {
List<PushTask> findByPushActions(Implementation pushActions);
+ List<MacroTask> findByCommand(Implementation delegate);
+
+ List<MacroTask> findByRealm(Realm realm);
+
<T extends Task<T>> List<T> findToExec(TaskType type);
<T extends Task<T>> List<T> findAll(TaskType type);
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/EntityFactory.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/EntityFactory.java
index ff2fd744dd..a74c4900b4 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/EntityFactory.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/EntityFactory.java
@@ -18,19 +18,15 @@
*/
package org.apache.syncope.core.persistence.api.entity;
-import org.apache.syncope.common.lib.types.TaskType;
import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
import org.apache.syncope.core.persistence.api.entity.user.User;
public interface EntityFactory {
<E extends Entity> E newEntity(Class<E> reference);
- <E extends TaskExec<?>> E newTaskExec(TaskType taskType);
-
ConnPoolConf newConnPoolConf();
Class<? extends User> userClass();
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ImplementationDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/MacroTask.java
similarity index 60%
copy from core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ImplementationDAO.java
copy to core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/MacroTask.java
index 44b19e9b70..29c68e044e 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ImplementationDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/MacroTask.java
@@ -16,20 +16,30 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.syncope.core.persistence.api.dao;
+package org.apache.syncope.core.persistence.api.entity.task;
import java.util.List;
+import org.apache.syncope.common.lib.command.CommandArgs;
import org.apache.syncope.core.persistence.api.entity.Implementation;
+import org.apache.syncope.core.persistence.api.entity.Realm;
-public interface ImplementationDAO extends DAO<Implementation> {
+public interface MacroTask extends SchedTask {
- Implementation find(String key);
+ Realm getRealm();
- List<Implementation> findByType(String type);
+ void setRealm(Realm realm);
- List<Implementation> findAll();
+ void add(Implementation command, CommandArgs args);
- Implementation save(Implementation implementation);
+ List<? extends Implementation> getCommands();
- void delete(String key);
+ List<CommandArgs> getCommandArgs();
+
+ boolean isContinueOnError();
+
+ void setContinueOnError(boolean continueOnError);
+
+ boolean isSaveExecs();
+
+ void setSaveExecs(boolean saveExecs);
}
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/TaskUtils.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/TaskUtils.java
index e8f5c15d38..c5c8336559 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/TaskUtils.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/TaskUtils.java
@@ -27,9 +27,19 @@ public interface TaskUtils {
<T extends Task<T>> T newTask();
+ <E extends TaskExec<?>> E newTaskExec();
+
<T extends TaskTO> T newTaskTO();
<T extends Task<T>> Class<T> taskClass();
<T extends TaskTO> Class<T> taskTOClass();
+
+ String getTaskTable();
+
+ Class<? extends Task<?>> getTaskEntity();
+
+ String getTaskExecTable();
+
+ Class<? extends TaskExec<?>> getTaskExecEntity();
}
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAJSONAnyObjectListener.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAJSONAnyObjectListener.java
index 0770da0498..0d4fdeeacd 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAJSONAnyObjectListener.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAJSONAnyObjectListener.java
@@ -32,10 +32,13 @@ import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
public class JPAJSONAnyObjectListener extends JPAJSONEntityListener<AnyObject> {
+ protected static final TypeReference<List<JPAJSONAPlainAttr>> TYPEREF =
+ new TypeReference<List<JPAJSONAPlainAttr>>() {
+ };
+
@Override
protected List<? extends JSONPlainAttr<AnyObject>> getAttrs(final String plainAttrsJSON) {
- return POJOHelper.deserialize(plainAttrsJSON, new TypeReference<List<JPAJSONAPlainAttr>>() {
- });
+ return POJOHelper.deserialize(plainAttrsJSON, TYPEREF);
}
@PostLoad
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAJSONGroupListener.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAJSONGroupListener.java
index 2c9fb34c83..ff071bb4f3 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAJSONGroupListener.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAJSONGroupListener.java
@@ -32,10 +32,13 @@ import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
public class JPAJSONGroupListener extends JPAJSONEntityListener<Group> {
+ protected static final TypeReference<List<JPAJSONGPlainAttr>> TYPEREF =
+ new TypeReference<List<JPAJSONGPlainAttr>>() {
+ };
+
@Override
protected List<? extends JSONPlainAttr<Group>> getAttrs(final String plainAttrsJSON) {
- return POJOHelper.deserialize(plainAttrsJSON, new TypeReference<List<JPAJSONGPlainAttr>>() {
- });
+ return POJOHelper.deserialize(plainAttrsJSON, TYPEREF);
}
@PostLoad
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONLinkedAccountListener.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONLinkedAccountListener.java
index 26436a4a16..8b54e0ffb4 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONLinkedAccountListener.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONLinkedAccountListener.java
@@ -32,10 +32,13 @@ import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
public class JPAJSONLinkedAccountListener extends JPAJSONEntityListener<User> {
+ protected static final TypeReference<List<JPAJSONLAPlainAttr>> TYPEREF =
+ new TypeReference<List<JPAJSONLAPlainAttr>>() {
+ };
+
@Override
protected List<? extends JSONLAPlainAttr> getAttrs(final String plainAttrsJSON) {
- return POJOHelper.deserialize(plainAttrsJSON, new TypeReference<List<JPAJSONLAPlainAttr>>() {
- });
+ return POJOHelper.deserialize(plainAttrsJSON, TYPEREF);
}
@PostLoad
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONUserListener.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONUserListener.java
index a2dadab626..0ea44a238e 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONUserListener.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONUserListener.java
@@ -32,10 +32,13 @@ import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
public class JPAJSONUserListener extends JPAJSONEntityListener<User> {
+ protected static final TypeReference<List<JPAJSONUPlainAttr>> TYPEREF =
+ new TypeReference<List<JPAJSONUPlainAttr>>() {
+ };
+
@Override
protected List<? extends JSONPlainAttr<User>> getAttrs(final String plainAttrsJSON) {
- return POJOHelper.deserialize(plainAttrsJSON, new TypeReference<List<JPAJSONUPlainAttr>>() {
- });
+ return POJOHelper.deserialize(plainAttrsJSON, TYPEREF);
}
@PostLoad
diff --git a/core/persistence-jpa-json/src/main/resources/domains/jpa-json/MasterContent.xml b/core/persistence-jpa-json/src/main/resources/domains/jpa-json/MasterContent.xml
index bfb31ffff2..fc6c0f4c16 100644
--- a/core/persistence-jpa-json/src/main/resources/domains/jpa-json/MasterContent.xml
+++ b/core/persistence-jpa-json/src/main/resources/domains/jpa-json/MasterContent.xml
@@ -39,6 +39,9 @@ under the License.
<Implementation id="BinaryValidator" type="VALIDATOR" engine="JAVA"
body="org.apache.syncope.core.persistence.jpa.attrvalue.validation.BinaryValidator"/>
+ <Implementation id="MacroRunJobDelegate" type="TASKJOB_DELEGATE" engine="JAVA"
+ body="org.apache.syncope.core.logic.job.MacroRunJobDelegate"/>
+
<Implementation id="PullJobDelegate" type="TASKJOB_DELEGATE" engine="JAVA"
body="org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate"/>
<Implementation id="PushJobDelegate" type="TASKJOB_DELEGATE" engine="JAVA"
diff --git a/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml
index 18e866db53..bed2f381a2 100644
--- a/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml
@@ -680,10 +680,14 @@ under the License.
<VirSchema id="virtualdata" READONLY="0" anyTypeClass_id="minimal user"
resource_id="resource-db-virattr" anyType_id="USER" extAttrName="USERNAME"/>
+ <Implementation id="MacroRunJobDelegate" type="TASKJOB_DELEGATE" engine="JAVA"
+ body="org.apache.syncope.core.logic.job.MacroRunJobDelegate"/>
+
<Implementation id="PullJobDelegate" type="TASKJOB_DELEGATE" engine="JAVA"
body="org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate"/>
<Implementation id="PushJobDelegate" type="TASKJOB_DELEGATE" engine="JAVA"
body="org.apache.syncope.core.provisioning.java.pushpull.PushJobDelegate"/>
+
<PropagationTask id="1e697572-b896-484c-ae7f-0c8f63fcbc6c" operation="UPDATE"
objectClassName="__ACCOUNT__" resource_id="ws-target-resource-2" anyTypeKind="USER" entityKey="1417acbe-cbf6-4277-9372-e75e04f97000"
propagationData='{"attributes":[{"name":"__PASSWORD__","value":[{"readOnly":false,"disposed":false,"encryptedBytes":"m9nh2US0Sa6m+cXccCq0Xw==","base64SHA1Hash":"GFJ69qfjxEOdrmt+9q+0Cw2uz60="}]},{"name":"__NAME__","value":["userId"],"nameValue":"userId"},{"name":"fullname","value":["fullname"]},{"name":"type","value":["type"]}]}'/>
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java
index cf95524230..97822c456e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java
@@ -299,8 +299,8 @@ public class PersistenceContext {
@ConditionalOnMissingBean
@Bean
- public TaskUtilsFactory taskUtilsFactory(final @Lazy EntityFactory entityFactory) {
- return new JPATaskUtilsFactory(entityFactory);
+ public TaskUtilsFactory taskUtilsFactory() {
+ return new JPATaskUtilsFactory();
}
@ConditionalOnMissingBean
@@ -581,13 +581,8 @@ public class PersistenceContext {
@ConditionalOnMissingBean
@Bean
- public RealmDAO realmDAO(
- final @Lazy RoleDAO roleDAO,
- final @Lazy CASSPClientAppDAO casSPClientAppDAO,
- final @Lazy OIDCRPClientAppDAO oidcRPClientAppDAO,
- final @Lazy SAML2SPClientAppDAO saml2SPClientAppDAO) {
-
- return new JPARealmDAO(roleDAO, casSPClientAppDAO, oidcRPClientAppDAO, saml2SPClientAppDAO);
+ public RealmDAO realmDAO(final @Lazy RoleDAO roleDAO) {
+ return new JPARealmDAO(roleDAO);
}
@ConditionalOnMissingBean
@@ -678,14 +673,19 @@ public class PersistenceContext {
@ConditionalOnMissingBean
@Bean
- public TaskDAO taskDAO(final RemediationDAO remediationDAO) {
- return new JPATaskDAO(remediationDAO);
+ public TaskDAO taskDAO(
+ final RealmDAO realmDAO,
+ final RemediationDAO remediationDAO,
+ final TaskUtilsFactory taskUtilsFactory,
+ final SecurityProperties securityProperties) {
+
+ return new JPATaskDAO(realmDAO, remediationDAO, taskUtilsFactory, securityProperties);
}
@ConditionalOnMissingBean
@Bean
- public TaskExecDAO taskExecDAO(final TaskDAO taskDAO) {
- return new JPATaskExecDAO(taskDAO);
+ public TaskExecDAO taskExecDAO(final TaskDAO taskDAO, final TaskUtilsFactory taskUtilsFactory) {
+ return new JPATaskExecDAO(taskDAO, taskUtilsFactory);
}
@ConditionalOnMissingBean
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultPullCorrelationRule.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultPullCorrelationRule.java
index 6d8dad2e0e..ada4b93904 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultPullCorrelationRule.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultPullCorrelationRule.java
@@ -60,9 +60,8 @@ public class DefaultPullCorrelationRule implements PullCorrelationRule {
List<SearchCond> searchConds = new ArrayList<>();
conf.getSchemas().forEach(schema -> {
- Item item = mappingItems.get(schema);
- Attribute attr = Optional.ofNullable(item).
- map(item1 -> syncDelta.getObject().getAttributeByName(item1.getExtAttrName())).orElse(null);
+ Attribute attr = Optional.ofNullable(mappingItems.get(schema)).
+ map(item -> syncDelta.getObject().getAttributeByName(item.getExtAttrName())).orElse(null);
if (attr == null) {
throw new IllegalArgumentException(
"Connector object does not contains the attributes to perform the search: " + schema);
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAImplementationDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAImplementationDAO.java
index be98681114..b063cf39fa 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAImplementationDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAImplementationDAO.java
@@ -20,6 +20,7 @@ package org.apache.syncope.core.persistence.jpa.dao;
import java.util.List;
import javax.persistence.TypedQuery;
+import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.core.persistence.api.dao.ImplementationDAO;
import org.apache.syncope.core.persistence.api.entity.Implementation;
import org.apache.syncope.core.persistence.jpa.entity.JPAImplementation;
@@ -37,12 +38,29 @@ public class JPAImplementationDAO extends AbstractDAO<Implementation> implements
@Override
public List<Implementation> findByType(final String type) {
TypedQuery<Implementation> query = entityManager().createQuery(
- "SELECT e FROM " + JPAImplementation.class.getSimpleName() + " e WHERE e.type=:type",
+ "SELECT e FROM " + JPAImplementation.class.getSimpleName() + " e WHERE e.type=:type ORDER BY e.id ASC",
Implementation.class);
query.setParameter("type", type);
return query.getResultList();
}
+ @Override
+ public List<Implementation> findByTypeAndKeyword(final String type, final String keyword) {
+ if (StringUtils.isBlank(keyword)) {
+ return findByType(type);
+ }
+
+ TypedQuery<Implementation> query = entityManager().createQuery(
+ "SELECT e FROM " + JPAImplementation.class.getSimpleName() + " e "
+ + "WHERE e.type=:type "
+ + "AND e.id LIKE :keyword "
+ + "ORDER BY e.id ASC",
+ Implementation.class);
+ query.setParameter("type", type);
+ query.setParameter("keyword", keyword);
+ return query.getResultList();
+ }
+
@Override
public List<Implementation> findAll() {
TypedQuery<Implementation> query = entityManager().createQuery(
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
index 9affc78f08..000824a700 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
@@ -25,12 +25,9 @@ import javax.persistence.NoResultException;
import javax.persistence.TypedQuery;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.core.persistence.api.dao.CASSPClientAppDAO;
import org.apache.syncope.core.persistence.api.dao.MalformedPathException;
-import org.apache.syncope.core.persistence.api.dao.OIDCRPClientAppDAO;
import org.apache.syncope.core.persistence.api.dao.RealmDAO;
import org.apache.syncope.core.persistence.api.dao.RoleDAO;
-import org.apache.syncope.core.persistence.api.dao.SAML2SPClientAppDAO;
import org.apache.syncope.core.persistence.api.entity.ExternalResource;
import org.apache.syncope.core.persistence.api.entity.Implementation;
import org.apache.syncope.core.persistence.api.entity.Realm;
@@ -49,22 +46,8 @@ public class JPARealmDAO extends AbstractDAO<Realm> implements RealmDAO {
protected final RoleDAO roleDAO;
- protected final CASSPClientAppDAO casSPClientAppDAO;
-
- protected final OIDCRPClientAppDAO oidcRPClientAppDAO;
-
- protected final SAML2SPClientAppDAO saml2SPClientAppDAO;
-
- public JPARealmDAO(
- final RoleDAO roleDAO,
- final CASSPClientAppDAO casSPClientAppDAO,
- final OIDCRPClientAppDAO oidcRPClientAppDAO,
- final SAML2SPClientAppDAO saml2SPClientAppDAO) {
-
+ public JPARealmDAO(final RoleDAO roleDAO) {
this.roleDAO = roleDAO;
- this.casSPClientAppDAO = casSPClientAppDAO;
- this.oidcRPClientAppDAO = oidcRPClientAppDAO;
- this.saml2SPClientAppDAO = saml2SPClientAppDAO;
}
@Override
@@ -258,10 +241,6 @@ public class JPARealmDAO extends AbstractDAO<Realm> implements RealmDAO {
findDescendants(realm).forEach(toBeDeleted -> {
roleDAO.findByRealm(toBeDeleted).forEach(role -> role.getRealms().remove(toBeDeleted));
- casSPClientAppDAO.findByRealm(toBeDeleted).forEach(clientApp -> clientApp.setRealm(null));
- oidcRPClientAppDAO.findByRealm(toBeDeleted).forEach(clientApp -> clientApp.setRealm(null));
- saml2SPClientAppDAO.findByRealm(toBeDeleted).forEach(clientApp -> clientApp.setRealm(null));
-
toBeDeleted.setParent(null);
entityManager().remove(toBeDeleted);
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
index 54e032243c..844d825bf7 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
@@ -22,6 +22,7 @@ import java.lang.reflect.Field;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.persistence.ManyToOne;
@@ -33,125 +34,64 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.lib.to.PropagationTaskTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.ExecStatus;
+import org.apache.syncope.common.lib.types.IdRepoEntitlement;
import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
import org.apache.syncope.core.persistence.api.dao.RemediationDAO;
import org.apache.syncope.core.persistence.api.dao.TaskDAO;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
import org.apache.syncope.core.persistence.api.entity.ExternalResource;
import org.apache.syncope.core.persistence.api.entity.Implementation;
import org.apache.syncope.core.persistence.api.entity.Notification;
-import org.apache.syncope.core.persistence.api.entity.task.NotificationTask;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.api.entity.task.MacroTask;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.persistence.api.entity.task.PullTask;
import org.apache.syncope.core.persistence.api.entity.task.PushTask;
import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
import org.apache.syncope.core.persistence.api.entity.task.Task;
+import org.apache.syncope.core.persistence.api.entity.task.TaskUtilsFactory;
+import org.apache.syncope.core.persistence.jpa.entity.task.JPAMacroTask;
import org.apache.syncope.core.persistence.jpa.entity.task.JPANotificationTask;
import org.apache.syncope.core.persistence.jpa.entity.task.JPAPropagationTask;
import org.apache.syncope.core.persistence.jpa.entity.task.JPAPropagationTaskExec;
import org.apache.syncope.core.persistence.jpa.entity.task.JPAPullTask;
import org.apache.syncope.core.persistence.jpa.entity.task.JPAPushTask;
import org.apache.syncope.core.persistence.jpa.entity.task.JPASchedTask;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.SecurityProperties;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ReflectionUtils;
public class JPATaskDAO extends AbstractDAO<Task<?>> implements TaskDAO {
- public static TaskType getTaskType(final Task<?> task) {
- if (task instanceof NotificationTask) {
- return TaskType.NOTIFICATION;
- }
-
- if (task instanceof PropagationTask) {
- return TaskType.PROPAGATION;
- }
-
- if (task instanceof PushTask) {
- return TaskType.PUSH;
- }
-
- if (task instanceof PullTask) {
- return TaskType.PULL;
- }
-
- if (task instanceof SchedTask) {
- return TaskType.SCHEDULED;
- }
-
- return null;
- }
-
- public static String getEntityTableName(final TaskType type) {
- String result = null;
-
- switch (type) {
- case NOTIFICATION:
- result = JPANotificationTask.TABLE;
- break;
-
- case PROPAGATION:
- result = JPAPropagationTask.TABLE;
- break;
+ protected final RealmDAO realmDAO;
- case PUSH:
- result = JPAPushTask.TABLE;
- break;
-
- case SCHEDULED:
- result = JPASchedTask.TABLE;
- break;
-
- case PULL:
- result = JPAPullTask.TABLE;
- break;
-
- default:
- }
-
- return result;
- }
-
- public static Class<? extends Task<?>> getEntityReference(final TaskType type) {
- Class<? extends Task<?>> result = null;
-
- switch (type) {
- case NOTIFICATION:
- result = JPANotificationTask.class;
- break;
-
- case PROPAGATION:
- result = JPAPropagationTask.class;
- break;
-
- case PUSH:
- result = JPAPushTask.class;
- break;
+ protected final RemediationDAO remediationDAO;
- case SCHEDULED:
- result = JPASchedTask.class;
- break;
+ protected final TaskUtilsFactory taskUtilsFactory;
- case PULL:
- result = JPAPullTask.class;
- break;
+ protected final SecurityProperties securityProperties;
- default:
- }
+ public JPATaskDAO(
+ final RealmDAO realmDAO,
+ final RemediationDAO remediationDAO,
+ final TaskUtilsFactory taskUtilsFactory,
+ final SecurityProperties securityProperties) {
- return result;
- }
-
- protected final RemediationDAO remediationDAO;
-
- public JPATaskDAO(final RemediationDAO remediationDAO) {
+ this.realmDAO = realmDAO;
this.remediationDAO = remediationDAO;
+ this.taskUtilsFactory = taskUtilsFactory;
+ this.securityProperties = securityProperties;
}
@Transactional(readOnly = true)
@Override
public boolean exists(final TaskType type, final String key) {
- Query query = entityManager().createNativeQuery("SELECT id FROM " + getEntityTableName(type) + " WHERE id=?");
+ Query query = entityManager().createNativeQuery("SELECT id FROM "
+ + taskUtilsFactory.getInstance(type).getTaskTable()
+ + " WHERE id=?");
query.setParameter(1, key);
return !query.getResultList().isEmpty();
@@ -161,7 +101,7 @@ public class JPATaskDAO extends AbstractDAO<Task<?>> implements TaskDAO {
@SuppressWarnings("unchecked")
@Override
public <T extends Task<T>> T find(final TaskType type, final String key) {
- return (T) entityManager().find(getEntityReference(type), key);
+ return (T) entityManager().find(taskUtilsFactory.getInstance(type).getTaskEntity(), key);
}
@Override
@@ -173,6 +113,9 @@ public class JPATaskDAO extends AbstractDAO<Task<?>> implements TaskDAO {
if (task == null) {
task = find(TaskType.PUSH, key);
}
+ if (task == null) {
+ task = find(TaskType.MACRO, key);
+ }
if (task == null) {
task = find(TaskType.PROPAGATION, key);
}
@@ -223,9 +166,28 @@ public class JPATaskDAO extends AbstractDAO<Task<?>> implements TaskDAO {
return query.getResultList();
}
+ @Override
+ public List<MacroTask> findByRealm(final Realm realm) {
+ TypedQuery<MacroTask> query = entityManager().createQuery(
+ "SELECT e FROM " + JPAMacroTask.class.getSimpleName() + " e "
+ + "WHERE e.realm=:realm", MacroTask.class);
+ query.setParameter("realm", realm);
+
+ return query.getResultList();
+ }
+
+ @Override
+ public List<MacroTask> findByCommand(final Implementation command) {
+ TypedQuery<MacroTask> query = entityManager().createQuery("SELECT e FROM " + JPAMacroTask.class.getSimpleName()
+ + " e WHERE :command MEMBER OF e.commands", MacroTask.class);
+ query.setParameter("command", command);
+
+ return query.getResultList();
+ }
+
protected final <T extends Task<T>> StringBuilder buildFindAllQueryJPA(final TaskType type) {
StringBuilder builder = new StringBuilder("SELECT t FROM ").
- append(getEntityReference(type).getSimpleName()).
+ append(taskUtilsFactory.getInstance(type).getTaskEntity().getSimpleName()).
append(" t WHERE ");
if (type == TaskType.SCHEDULED) {
builder.append("t.id NOT IN (SELECT t.id FROM ").
@@ -262,6 +224,11 @@ public class JPATaskDAO extends AbstractDAO<Task<?>> implements TaskDAO {
return findAll(type, null, null, null, null, -1, -1, List.of());
}
+ protected int setParameter(final List<Object> parameters, final Object parameter) {
+ parameters.add(parameter);
+ return parameters.size();
+ }
+
protected StringBuilder buildFindAllQuery(
final TaskType type,
final ExternalResource resource,
@@ -269,7 +236,7 @@ public class JPATaskDAO extends AbstractDAO<Task<?>> implements TaskDAO {
final AnyTypeKind anyTypeKind,
final String entityKey,
final boolean orderByTaskExecInfo,
- final List<Object> queryParameters) {
+ final List<Object> parameters) {
if (resource != null
&& type != TaskType.PROPAGATION && type != TaskType.PUSH && type != TaskType.PULL) {
@@ -287,55 +254,60 @@ public class JPATaskDAO extends AbstractDAO<Task<?>> implements TaskDAO {
throw new IllegalArgumentException(type + " is not related to notifications");
}
- String table = getEntityTableName(type);
- StringBuilder queryString = new StringBuilder("SELECT ").append(table).append(".*");
+ String taskTable = taskUtilsFactory.getInstance(type).getTaskTable();
+ StringBuilder queryString = new StringBuilder("SELECT ").append(taskTable).append(".*");
if (orderByTaskExecInfo) {
- queryString.append(',').append(JPATaskExecDAO.getEntityTableName(type)).append(".startDate AS startDate").
- append(',').append(JPATaskExecDAO.getEntityTableName(type)).append(".endDate AS endDate").
- append(',').append(JPATaskExecDAO.getEntityTableName(type)).append(".status AS status").
- append(" FROM ").append(table).
- append(',').append(JPATaskExecDAO.getEntityTableName(type)).append(',').append("(SELECT ").
- append(JPATaskExecDAO.getEntityTableName(type)).append(".task_id, ").
- append("MAX(").append(JPATaskExecDAO.getEntityTableName(type)).append(".startDate) AS startDate").
- append(" FROM ").append(JPATaskExecDAO.getEntityTableName(type)).
- append(" GROUP BY ").append(JPATaskExecDAO.getEntityTableName(type)).append(".task_id) GRP").
+ String taskExecTable = taskUtilsFactory.getInstance(type).getTaskExecTable();
+ queryString.append(',').append(taskExecTable).append(".startDate AS startDate").
+ append(',').append(taskExecTable).append(".endDate AS endDate").
+ append(',').append(taskExecTable).append(".status AS status").
+ append(" FROM ").append(taskTable).
+ append(',').append(taskExecTable).append(',').append("(SELECT ").
+ append(taskExecTable).append(".task_id, ").
+ append("MAX(").append(taskExecTable).append(".startDate) AS startDate").
+ append(" FROM ").append(taskExecTable).
+ append(" GROUP BY ").append(taskExecTable).append(".task_id) GRP").
append(" WHERE ").
- append(table).append(".id=").append(JPATaskExecDAO.getEntityTableName(type)).append(".task_id").
- append(" AND ").append(table).append(".id=").append("GRP.task_id").
+ append(taskTable).append(".id=").append(taskExecTable).append(".task_id").
+ append(" AND ").append(taskTable).append(".id=").append("GRP.task_id").
append(" AND ").
- append(JPATaskExecDAO.getEntityTableName(type)).append(".startDate=").append("GRP.startDate");
+ append(taskExecTable).append(".startDate=").append("GRP.startDate");
} else {
- queryString.append(", null AS startDate, null AS endDate, null AS status FROM ").append(table).
- append(" WHERE 1=1 ");
+ queryString.append(", null AS startDate, null AS endDate, null AS status FROM ").append(taskTable).
+ append(" WHERE 1=1");
}
queryString.append(' ');
if (resource != null) {
- queryParameters.add(resource.getKey());
-
queryString.append(" AND ").
- append(table).
- append(".resource_id=?").append(queryParameters.size());
+ append(taskTable).append(".resource_id=?").append(setParameter(parameters, resource.getKey()));
}
if (notification != null) {
- queryParameters.add(notification.getKey());
-
queryString.append(" AND ").
- append(table).
- append(".notification_id=?").append(queryParameters.size());
+ append(taskTable).
+ append(".notification_id=?").append(setParameter(parameters, notification.getKey()));
}
if (anyTypeKind != null && entityKey != null) {
- queryParameters.add(anyTypeKind.name());
- queryParameters.add(entityKey);
-
queryString.append(" AND ").
- append(table).
- append(".anyTypeKind=?").append(queryParameters.size() - 1).
+ append(taskTable).append(".anyTypeKind=?").append(setParameter(parameters, anyTypeKind.name())).
append(" AND ").
- append(table).
- append(".entityKey=?").append(queryParameters.size());
+ append(taskTable).append(".entityKey=?").append(setParameter(parameters, entityKey));
+ }
+ if (type == TaskType.MACRO
+ && !AuthContextUtils.getUsername().equals(securityProperties.getAdminUser())) {
+
+ String realmKeysArg = AuthContextUtils.getAuthorizations().get(IdRepoEntitlement.TASK_LIST).stream().
+ map(realmDAO::findByFullPath).
+ filter(Objects::nonNull).
+ flatMap(r -> realmDAO.findDescendants(r).stream()).
+ map(Realm::getKey).
+ distinct().
+ map(realmKey -> "?" + setParameter(parameters, realmKey)).
+ collect(Collectors.joining(","));
+ queryString.append(" AND ").
+ append(taskTable).append(".realm_id IN (").append(realmKeysArg).append(")");
}
return queryString;
@@ -400,7 +372,7 @@ public class JPATaskDAO extends AbstractDAO<Task<?>> implements TaskDAO {
final int itemsPerPage,
final List<OrderByClause> orderByClauses) {
- List<Object> queryParameters = new ArrayList<>();
+ List<Object> parameters = new ArrayList<>();
boolean orderByTaskExecInfo = orderByClauses.stream().
anyMatch(clause -> clause.getField().equals("start")
@@ -415,7 +387,7 @@ public class JPATaskDAO extends AbstractDAO<Task<?>> implements TaskDAO {
anyTypeKind,
entityKey,
orderByTaskExecInfo,
- queryParameters);
+ parameters);
if (orderByTaskExecInfo) {
// UNION with tasks without executions...
@@ -427,20 +399,22 @@ public class JPATaskDAO extends AbstractDAO<Task<?>> implements TaskDAO {
anyTypeKind,
entityKey,
false,
- queryParameters)).
+ parameters)).
append(" AND id NOT IN ").
- append("(SELECT task_id AS id FROM ").append(JPATaskExecDAO.getEntityTableName(type)).append(')').
+ append("(SELECT task_id AS id FROM ").
+ append(taskUtilsFactory.getInstance(type).getTaskExecTable()).
+ append(')').
append(")) T");
} else {
queryString.insert(0, "SELECT T.id FROM (").append(") T");
}
- queryString.append(toOrderByStatement(getEntityReference(type), orderByClauses));
+ queryString.append(toOrderByStatement(taskUtilsFactory.getInstance(type).getTaskEntity(), orderByClauses));
Query query = entityManager().createNativeQuery(queryString.toString());
- for (int i = 1; i <= queryParameters.size(); i++) {
- query.setParameter(i, queryParameters.get(i - 1));
+ for (int i = 1; i <= parameters.size(); i++) {
+ query.setParameter(i, parameters.get(i - 1));
}
query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));
@@ -476,18 +450,19 @@ public class JPATaskDAO extends AbstractDAO<Task<?>> implements TaskDAO {
final AnyTypeKind anyTypeKind,
final String entityKey) {
- List<Object> queryParameters = new ArrayList<>();
+ List<Object> parameters = new ArrayList<>();
StringBuilder queryString =
- buildFindAllQuery(type, resource, notification, anyTypeKind, entityKey, false, queryParameters);
+ buildFindAllQuery(type, resource, notification, anyTypeKind, entityKey, false, parameters);
+ String table = taskUtilsFactory.getInstance(type).getTaskTable();
Query query = entityManager().createNativeQuery(StringUtils.replaceOnce(
queryString.toString(),
- "SELECT " + getEntityTableName(type) + ".*, null AS startDate, null AS endDate, null AS status",
- "SELECT COUNT(" + getEntityTableName(type) + ".id)"));
+ "SELECT " + table + ".*, null AS startDate, null AS endDate, null AS status",
+ "SELECT COUNT(" + table + ".id)"));
- for (int i = 1; i <= queryParameters.size(); i++) {
- query.setParameter(i, queryParameters.get(i - 1));
+ for (int i = 1; i <= parameters.size(); i++) {
+ query.setParameter(i, parameters.get(i - 1));
}
return ((Number) query.getSingleResult()).intValue();
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskExecDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskExecDAO.java
index dbf6645e6e..e6f08ab786 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskExecDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskExecDAO.java
@@ -31,87 +31,26 @@ import org.apache.syncope.core.persistence.api.dao.TaskExecDAO;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
import org.apache.syncope.core.persistence.api.entity.task.Task;
import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
+import org.apache.syncope.core.persistence.api.entity.task.TaskUtilsFactory;
import org.apache.syncope.core.persistence.jpa.entity.task.AbstractTaskExec;
-import org.apache.syncope.core.persistence.jpa.entity.task.JPANotificationTaskExec;
-import org.apache.syncope.core.persistence.jpa.entity.task.JPAPropagationTaskExec;
-import org.apache.syncope.core.persistence.jpa.entity.task.JPAPullTaskExec;
-import org.apache.syncope.core.persistence.jpa.entity.task.JPAPushTaskExec;
-import org.apache.syncope.core.persistence.jpa.entity.task.JPASchedTaskExec;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ReflectionUtils;
public class JPATaskExecDAO extends AbstractDAO<TaskExec<?>> implements TaskExecDAO {
- public static String getEntityTableName(final TaskType type) {
- String result = null;
-
- switch (type) {
- case NOTIFICATION:
- result = JPANotificationTaskExec.TABLE;
- break;
-
- case PROPAGATION:
- result = JPAPropagationTaskExec.TABLE;
- break;
-
- case PUSH:
- result = JPAPushTaskExec.TABLE;
- break;
-
- case SCHEDULED:
- result = JPASchedTaskExec.TABLE;
- break;
-
- case PULL:
- result = JPAPullTaskExec.TABLE;
- break;
-
- default:
- }
-
- return result;
- }
-
- protected static Class<? extends TaskExec<?>> getEntityReference(final TaskType type) {
- Class<? extends TaskExec<?>> result = null;
-
- switch (type) {
- case NOTIFICATION:
- result = JPANotificationTaskExec.class;
- break;
-
- case PROPAGATION:
- result = JPAPropagationTaskExec.class;
- break;
-
- case PUSH:
- result = JPAPushTaskExec.class;
- break;
-
- case SCHEDULED:
- result = JPASchedTaskExec.class;
- break;
-
- case PULL:
- result = JPAPullTaskExec.class;
- break;
-
- default:
- }
-
- return result;
- }
-
protected final TaskDAO taskDAO;
- public JPATaskExecDAO(final TaskDAO taskDAO) {
+ protected final TaskUtilsFactory taskUtilsFactory;
+
+ public JPATaskExecDAO(final TaskDAO taskDAO, final TaskUtilsFactory taskUtilsFactory) {
this.taskDAO = taskDAO;
+ this.taskUtilsFactory = taskUtilsFactory;
}
@SuppressWarnings("unchecked")
@Override
public <T extends Task<T>> TaskExec<T> find(final TaskType type, final String key) {
- return (TaskExec<T>) entityManager().find(getEntityReference(type), key);
+ return (TaskExec<T>) entityManager().find(taskUtilsFactory.getInstance(type).getTaskExecEntity(), key);
}
@Override
@@ -123,6 +62,9 @@ public class JPATaskExecDAO extends AbstractDAO<TaskExec<?>> implements TaskExec
if (task == null) {
task = find(TaskType.PUSH, key);
}
+ if (task == null) {
+ task = find(TaskType.MACRO, key);
+ }
if (task == null) {
task = find(TaskType.PROPAGATION, key);
}
@@ -136,7 +78,7 @@ public class JPATaskExecDAO extends AbstractDAO<TaskExec<?>> implements TaskExec
@SuppressWarnings("unchecked")
protected <T extends Task<T>> List<TaskExec<T>> findRecent(final TaskType type, final int max) {
Query query = entityManager().createQuery(
- "SELECT e FROM " + getEntityReference(type).getSimpleName() + " e "
+ "SELECT e FROM " + taskUtilsFactory.getInstance(type).getTaskExecEntity().getSimpleName() + " e "
+ "WHERE e.end IS NOT NULL ORDER BY e.end DESC");
query.setMaxResults(max);
@@ -161,7 +103,7 @@ public class JPATaskExecDAO extends AbstractDAO<TaskExec<?>> implements TaskExec
@SuppressWarnings("unchecked")
protected TaskExec<?> findLatest(final TaskType type, final Task<?> task, final String field) {
Query query = entityManager().createQuery(
- "SELECT e FROM " + getEntityReference(type).getSimpleName() + " e "
+ "SELECT e FROM " + taskUtilsFactory.getInstance(type).getTaskExecEntity().getSimpleName() + " e "
+ "WHERE e.task=:task ORDER BY e." + field + " DESC");
query.setParameter("task", task);
query.setMaxResults(1);
@@ -192,7 +134,7 @@ public class JPATaskExecDAO extends AbstractDAO<TaskExec<?>> implements TaskExec
final OffsetDateTime endedAfter) {
StringBuilder queryString = new StringBuilder("SELECT e FROM ").
- append(getEntityReference(JPATaskDAO.getTaskType(task)).getSimpleName()).
+ append(taskUtilsFactory.getInstance(task).getTaskExecEntity().getSimpleName()).
append(" e WHERE e.task=:task ");
if (startedBefore != null) {
@@ -230,7 +172,7 @@ public class JPATaskExecDAO extends AbstractDAO<TaskExec<?>> implements TaskExec
@Override
public int count(final Task<?> task) {
Query countQuery = entityManager().createNativeQuery(
- "SELECT COUNT(e.id) FROM " + getEntityTableName(JPATaskDAO.getTaskType(task)) + " e "
+ "SELECT COUNT(e.id) FROM " + taskUtilsFactory.getInstance(task).getTaskExecTable() + " e "
+ "WHERE e.task_id=?1");
countQuery.setParameter(1, task.getKey());
@@ -261,7 +203,7 @@ public class JPATaskExecDAO extends AbstractDAO<TaskExec<?>> implements TaskExec
final Task<?> task, final int page, final int itemsPerPage, final List<OrderByClause> orderByClauses) {
String queryString = "SELECT e "
- + "FROM " + getEntityReference(JPATaskDAO.getTaskType(task)).getSimpleName() + " e "
+ + "FROM " + taskUtilsFactory.getInstance(task).getTaskExecEntity().getSimpleName() + " e "
+ "WHERE e.task=:task "
+ toOrderByStatement(orderByClauses);
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
index 2b0b1d8d56..253e6b272e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
@@ -58,6 +58,10 @@ public class JPAConnInstance extends AbstractGeneratedKeyEntity implements ConnI
public static final String TABLE = "ConnInstance";
+ protected static final TypeReference<Set<ConnectorCapability>> TYPEREF =
+ new TypeReference<Set<ConnectorCapability>>() {
+ };
+
private static final int DEFAULT_TIMEOUT = 10;
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@@ -246,9 +250,7 @@ public class JPAConnInstance extends AbstractGeneratedKeyEntity implements ConnI
getCapabilities().clear();
}
if (capabilities != null) {
- getCapabilities().addAll(
- POJOHelper.deserialize(capabilities, new TypeReference<Set<ConnectorCapability>>() {
- }));
+ getCapabilities().addAll(POJOHelper.deserialize(capabilities, TYPEREF));
}
}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
index 1da1fb5d43..0b9ee7c7df 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
@@ -18,7 +18,6 @@
*/
package org.apache.syncope.core.persistence.jpa.entity;
-import org.apache.syncope.common.lib.types.TaskType;
import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
import org.apache.syncope.core.persistence.api.entity.AccessToken;
import org.apache.syncope.core.persistence.api.entity.AnyAbout;
@@ -86,13 +85,13 @@ import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy;
import org.apache.syncope.core.persistence.api.entity.policy.PushCorrelationRuleEntity;
import org.apache.syncope.core.persistence.api.entity.policy.PushPolicy;
import org.apache.syncope.core.persistence.api.entity.task.AnyTemplatePullTask;
+import org.apache.syncope.core.persistence.api.entity.task.MacroTask;
import org.apache.syncope.core.persistence.api.entity.task.NotificationTask;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.persistence.api.entity.task.PullTask;
import org.apache.syncope.core.persistence.api.entity.task.PushTask;
import org.apache.syncope.core.persistence.api.entity.task.PushTaskAnyFilter;
import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
-import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
import org.apache.syncope.core.persistence.api.entity.user.DynRoleMembership;
import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttr;
import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttrUniqueValue;
@@ -140,17 +139,13 @@ import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPullPolicy;
import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPushCorrelationRuleEntity;
import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPushPolicy;
import org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyTemplatePullTask;
+import org.apache.syncope.core.persistence.jpa.entity.task.JPAMacroTask;
import org.apache.syncope.core.persistence.jpa.entity.task.JPANotificationTask;
-import org.apache.syncope.core.persistence.jpa.entity.task.JPANotificationTaskExec;
import org.apache.syncope.core.persistence.jpa.entity.task.JPAPropagationTask;
-import org.apache.syncope.core.persistence.jpa.entity.task.JPAPropagationTaskExec;
import org.apache.syncope.core.persistence.jpa.entity.task.JPAPullTask;
-import org.apache.syncope.core.persistence.jpa.entity.task.JPAPullTaskExec;
import org.apache.syncope.core.persistence.jpa.entity.task.JPAPushTask;
import org.apache.syncope.core.persistence.jpa.entity.task.JPAPushTaskAnyFilter;
-import org.apache.syncope.core.persistence.jpa.entity.task.JPAPushTaskExec;
import org.apache.syncope.core.persistence.jpa.entity.task.JPASchedTask;
-import org.apache.syncope.core.persistence.jpa.entity.task.JPASchedTaskExec;
import org.apache.syncope.core.persistence.jpa.entity.user.JPADynRoleMembership;
import org.apache.syncope.core.persistence.jpa.entity.user.JPALAPlainAttr;
import org.apache.syncope.core.persistence.jpa.entity.user.JPALAPlainAttrUniqueValue;
@@ -281,6 +276,8 @@ public class JPAEntityFactory implements EntityFactory {
result = (E) new JPAPushTask();
} else if (reference.equals(PullTask.class)) {
result = (E) new JPAPullTask();
+ } else if (reference.equals(MacroTask.class)) {
+ result = (E) new JPAMacroTask();
} else if (reference.equals(SchedTask.class)) {
result = (E) new JPASchedTask();
} else if (reference.equals(PushTaskAnyFilter.class)) {
@@ -348,43 +345,6 @@ public class JPAEntityFactory implements EntityFactory {
return result;
}
- @SuppressWarnings("unchecked")
- @Override
- public <E extends TaskExec<?>> E newTaskExec(final TaskType taskType) {
- E result;
-
- switch (taskType) {
- case NOTIFICATION:
- result = (E) new JPANotificationTaskExec();
- break;
-
- case PROPAGATION:
- result = (E) new JPAPropagationTaskExec();
- break;
-
- case PULL:
- result = (E) new JPAPullTaskExec();
- break;
-
- case PUSH:
- result = (E) new JPAPushTaskExec();
- break;
-
- case SCHEDULED:
- result = (E) new JPASchedTaskExec();
- break;
-
- default:
- result = null;
- }
-
- if (result instanceof AbstractGeneratedKeyEntity) {
- ((AbstractGeneratedKeyEntity) result).setKey(SecureRandomUtils.generateRandomUUID().toString());
- }
-
- return result;
- }
-
@Override
public ConnPoolConf newConnPoolConf() {
return new JPAConnPoolConf();
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAExternalResource.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAExternalResource.java
index 3ecabb3837..5a5b1602a1 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAExternalResource.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAExternalResource.java
@@ -81,6 +81,14 @@ public class JPAExternalResource extends AbstractProvidedKeyEntity implements Ex
public static final String TABLE = "ExternalResource";
+ protected static final TypeReference<Set<ConnectorCapability>> CAPABILITY_TYPEREF =
+ new TypeReference<Set<ConnectorCapability>>() {
+ };
+
+ protected static final TypeReference<List<Provision>> PROVISION_TYPEREF =
+ new TypeReference<List<Provision>>() {
+ };
+
/**
* Should this resource enforce the mandatory constraints?
*/
@@ -397,14 +405,10 @@ public class JPAExternalResource extends AbstractProvidedKeyEntity implements Ex
getProvisions().clear();
}
if (capabilitiesOverride != null) {
- getCapabilitiesOverride().addAll(
- POJOHelper.deserialize(capabilitiesOverride, new TypeReference<Set<ConnectorCapability>>() {
- }));
+ getCapabilitiesOverride().addAll(POJOHelper.deserialize(capabilitiesOverride, CAPABILITY_TYPEREF));
}
if (provisions != null) {
- getProvisions().addAll(
- POJOHelper.deserialize(provisions, new TypeReference<List<Provision>>() {
- }));
+ getProvisions().addAll(POJOHelper.deserialize(provisions, PROVISION_TYPEREF));
}
}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPANotification.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPANotification.java
index be5dde761a..a3e7a82ce4 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPANotification.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPANotification.java
@@ -56,6 +56,9 @@ public class JPANotification extends AbstractGeneratedKeyEntity implements Notif
public static final String TABLE = "Notification";
+ protected static final TypeReference<List<String>> TYPEREF = new TypeReference<List<String>>() {
+ };
+
@Lob
private String events;
@@ -225,14 +228,10 @@ public class JPANotification extends AbstractGeneratedKeyEntity implements Notif
getStaticRecipients().clear();
}
if (events != null) {
- getEvents().addAll(
- POJOHelper.deserialize(events, new TypeReference<List<String>>() {
- }));
+ getEvents().addAll(POJOHelper.deserialize(events, TYPEREF));
}
if (staticRecipients != null) {
- getStaticRecipients().addAll(
- POJOHelper.deserialize(staticRecipients, new TypeReference<List<String>>() {
- }));
+ getStaticRecipients().addAll(POJOHelper.deserialize(staticRecipients, TYPEREF));
}
}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARole.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARole.java
index ce773105da..6834b15cb4 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARole.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARole.java
@@ -62,6 +62,9 @@ public class JPARole extends AbstractProvidedKeyEntity implements Role {
public static final String TABLE = "SyncopeRole";
+ protected static final TypeReference<Set<String>> TYPEREF = new TypeReference<Set<String>>() {
+ };
+
@Lob
private String entitlements;
@@ -177,8 +180,7 @@ public class JPARole extends AbstractProvidedKeyEntity implements Role {
}
if (entitlements != null) {
getEntitlements().addAll(
- POJOHelper.deserialize(entitlements, new TypeReference<Set<String>>() {
- }));
+ POJOHelper.deserialize(entitlements, TYPEREF));
}
}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/AbstractClientApp.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/AbstractClientApp.java
index 60301830ab..2241f7bc29 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/AbstractClientApp.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/AbstractClientApp.java
@@ -44,6 +44,9 @@ public class AbstractClientApp extends AbstractGeneratedKeyEntity implements Cli
private static final long serialVersionUID = 7422422526695279794L;
+ protected static final TypeReference<List<Attr>> ATTR_TYPEREF = new TypeReference<List<Attr>>() {
+ };
+
@Column(unique = true, nullable = false)
private String name;
@@ -159,8 +162,7 @@ public class AbstractClientApp extends AbstractGeneratedKeyEntity implements Cli
public List<Attr> getProperties() {
return properties == null
? new ArrayList<>(0)
- : POJOHelper.deserialize(properties, new TypeReference<>() {
- });
+ : POJOHelper.deserialize(properties, ATTR_TYPEREF);
}
@Override
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAAttrRepo.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAAttrRepo.java
index 9f452b69fc..b9b8adb137 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAAttrRepo.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAAttrRepo.java
@@ -46,9 +46,12 @@ import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
@Table(name = JPAAttrRepo.TABLE)
public class JPAAttrRepo extends AbstractProvidedKeyEntity implements AttrRepo {
+ private static final long serialVersionUID = 7337970107878689617L;
+
public static final String TABLE = "AttrRepo";
- private static final long serialVersionUID = 7337970107878689617L;
+ protected static final TypeReference<List<Item>> TYPEREF = new TypeReference<List<Item>>() {
+ };
private String description;
@@ -123,9 +126,7 @@ public class JPAAttrRepo extends AbstractProvidedKeyEntity implements AttrRepo {
getItems().clear();
}
if (items != null) {
- getItems().addAll(
- POJOHelper.deserialize(items, new TypeReference<List<Item>>() {
- }));
+ getItems().addAll(POJOHelper.deserialize(items, TYPEREF));
}
}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAAuthModule.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAAuthModule.java
index 527fe81de6..3bbaf9d8b0 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAAuthModule.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAAuthModule.java
@@ -46,9 +46,12 @@ import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
@Table(name = JPAAuthModule.TABLE)
public class JPAAuthModule extends AbstractProvidedKeyEntity implements AuthModule {
+ private static final long serialVersionUID = 5681033638234853077L;
+
public static final String TABLE = "AuthModule";
- private static final long serialVersionUID = 5681033638234853077L;
+ protected static final TypeReference<List<Item>> TYPEREF = new TypeReference<List<Item>>() {
+ };
private String description;
@@ -123,9 +126,7 @@ public class JPAAuthModule extends AbstractProvidedKeyEntity implements AuthModu
getItems().clear();
}
if (items != null) {
- getItems().addAll(
- POJOHelper.deserialize(items, new TypeReference<List<Item>>() {
- }));
+ getItems().addAll(POJOHelper.deserialize(items, TYPEREF));
}
}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAAuthProfile.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAAuthProfile.java
index 7ac8baa57a..e8349e11ac 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAAuthProfile.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAAuthProfile.java
@@ -41,9 +41,28 @@ import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
@UniqueConstraint(columnNames = { "owner" }))
public class JPAAuthProfile extends AbstractGeneratedKeyEntity implements AuthProfile {
+ private static final long serialVersionUID = 57352617217394093L;
+
public static final String TABLE = "AuthProfile";
- private static final long serialVersionUID = 57352617217394093L;
+ protected static final TypeReference<List<GoogleMfaAuthToken>> GOOGLE_MFA_TOKENS_TYPEREF =
+ new TypeReference<List<GoogleMfaAuthToken>>() {
+ };
+
+ protected static final TypeReference<List<GoogleMfaAuthAccount>> GOOGLE_MFA_ACCOUNTS_TYPEREF =
+ new TypeReference<List<GoogleMfaAuthAccount>>() {
+ };
+
+ protected static final TypeReference<List<U2FDevice>> U2F_TYPEREF = new TypeReference<List<U2FDevice>>() {
+ };
+
+ protected static final TypeReference<List<ImpersonationAccount>> IMPERSONATION_TYPEREF =
+ new TypeReference<List<ImpersonationAccount>>() {
+ };
+
+ protected static final TypeReference<List<WebAuthnDeviceCredential>> WEBAUTHN_TYPEREF =
+ new TypeReference<List<WebAuthnDeviceCredential>>() {
+ };
@Column(nullable = false)
private String owner;
@@ -76,8 +95,7 @@ public class JPAAuthProfile extends AbstractGeneratedKeyEntity implements AuthPr
@Override
public List<GoogleMfaAuthToken> getGoogleMfaAuthTokens() {
return Optional.ofNullable(googleMfaAuthTokens).
- map(v -> POJOHelper.deserialize(v, new TypeReference<List<GoogleMfaAuthToken>>() {
- })).orElseGet(() -> new ArrayList<>(0));
+ map(v -> POJOHelper.deserialize(v, GOOGLE_MFA_TOKENS_TYPEREF)).orElseGet(() -> new ArrayList<>(0));
}
@Override
@@ -88,8 +106,7 @@ public class JPAAuthProfile extends AbstractGeneratedKeyEntity implements AuthPr
@Override
public List<GoogleMfaAuthAccount> getGoogleMfaAuthAccounts() {
return Optional.ofNullable(googleMfaAuthAccounts).
- map(v -> POJOHelper.deserialize(v, new TypeReference<List<GoogleMfaAuthAccount>>() {
- })).orElseGet(() -> new ArrayList<>(0));
+ map(v -> POJOHelper.deserialize(v, GOOGLE_MFA_ACCOUNTS_TYPEREF)).orElseGet(() -> new ArrayList<>(0));
}
@Override
@@ -100,8 +117,7 @@ public class JPAAuthProfile extends AbstractGeneratedKeyEntity implements AuthPr
@Override
public List<U2FDevice> getU2FRegisteredDevices() {
return Optional.ofNullable(u2fRegisteredDevices).
- map(v -> POJOHelper.deserialize(v, new TypeReference<List<U2FDevice>>() {
- })).orElseGet(() -> new ArrayList<>(0));
+ map(v -> POJOHelper.deserialize(v, U2F_TYPEREF)).orElseGet(() -> new ArrayList<>(0));
}
@Override
@@ -112,8 +128,7 @@ public class JPAAuthProfile extends AbstractGeneratedKeyEntity implements AuthPr
@Override
public List<ImpersonationAccount> getImpersonationAccounts() {
return Optional.ofNullable(impersonationAccounts).
- map(v -> POJOHelper.deserialize(v, new TypeReference<List<ImpersonationAccount>>() {
- })).orElseGet(() -> new ArrayList<>(0));
+ map(v -> POJOHelper.deserialize(v, IMPERSONATION_TYPEREF)).orElseGet(() -> new ArrayList<>(0));
}
@Override
@@ -124,8 +139,7 @@ public class JPAAuthProfile extends AbstractGeneratedKeyEntity implements AuthPr
@Override
public List<WebAuthnDeviceCredential> getWebAuthnDeviceCredentials() {
return Optional.ofNullable(webAuthnDeviceCredentials).
- map(v -> POJOHelper.deserialize(v, new TypeReference<List<WebAuthnDeviceCredential>>() {
- })).orElseGet(() -> new ArrayList<>(0));
+ map(v -> POJOHelper.deserialize(v, WEBAUTHN_TYPEREF)).orElseGet(() -> new ArrayList<>(0));
}
@Override
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAOIDCRPClientApp.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAOIDCRPClientApp.java
index 3ca91b1b80..fbd172e512 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAOIDCRPClientApp.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAOIDCRPClientApp.java
@@ -47,6 +47,17 @@ public class JPAOIDCRPClientApp extends AbstractClientApp implements OIDCRPClien
public static final String TABLE = "OIDCRPClientApp";
+ protected static final TypeReference<Set<String>> STRING_TYPEREF = new TypeReference<Set<String>>() {
+ };
+
+ protected static final TypeReference<Set<OIDCGrantType>> GRANT_TYPE_TYPEREF =
+ new TypeReference<Set<OIDCGrantType>>() {
+ };
+
+ protected static final TypeReference<Set<OIDCResponseType>> RESPONSE_TYPE_TYPEREF =
+ new TypeReference<Set<OIDCResponseType>>() {
+ };
+
@Column(unique = true, nullable = false)
private String clientId;
@@ -173,19 +184,13 @@ public class JPAOIDCRPClientApp extends AbstractClientApp implements OIDCRPClien
getSupportedResponseTypes().clear();
}
if (redirectUris != null) {
- getRedirectUris().addAll(
- POJOHelper.deserialize(redirectUris, new TypeReference<Set<String>>() {
- }));
+ getRedirectUris().addAll(POJOHelper.deserialize(redirectUris, STRING_TYPEREF));
}
if (supportedGrantTypes != null) {
- getSupportedGrantTypes().addAll(
- POJOHelper.deserialize(supportedGrantTypes, new TypeReference<Set<OIDCGrantType>>() {
- }));
+ getSupportedGrantTypes().addAll(POJOHelper.deserialize(supportedGrantTypes, GRANT_TYPE_TYPEREF));
}
if (supportedResponseTypes != null) {
- getSupportedResponseTypes().addAll(
- POJOHelper.deserialize(supportedResponseTypes, new TypeReference<Set<OIDCResponseType>>() {
- }));
+ getSupportedResponseTypes().addAll(POJOHelper.deserialize(supportedResponseTypes, RESPONSE_TYPE_TYPEREF));
}
}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPASAML2SPClientApp.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPASAML2SPClientApp.java
index 555f5d0086..7b9c05e9f2 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPASAML2SPClientApp.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPASAML2SPClientApp.java
@@ -42,9 +42,16 @@ import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
@Table(name = JPASAML2SPClientApp.TABLE)
public class JPASAML2SPClientApp extends AbstractClientApp implements SAML2SPClientApp {
+ private static final long serialVersionUID = 6422422526695279794L;
+
public static final String TABLE = "SAML2SPClientApp";
- private static final long serialVersionUID = 6422422526695279794L;
+ protected static final TypeReference<Set<String>> STRING_TYPEREF = new TypeReference<Set<String>>() {
+ };
+
+ protected static final TypeReference<List<XmlSecAlgorithm>> XMLSECAGO_TYPEREF =
+ new TypeReference<List<XmlSecAlgorithm>>() {
+ };
@Column(unique = true, nullable = false)
private String entityId;
@@ -289,45 +296,31 @@ public class JPASAML2SPClientApp extends AbstractClientApp implements SAML2SPCli
}
if (assertionAudiences != null) {
getAssertionAudiences().addAll(
- POJOHelper.deserialize(assertionAudiences,
- new TypeReference<Set<String>>() {
- }));
+ POJOHelper.deserialize(assertionAudiences, STRING_TYPEREF));
}
if (signingSignatureAlgorithms != null) {
getSigningSignatureAlgorithms().addAll(
- POJOHelper.deserialize(signingSignatureAlgorithms,
- new TypeReference<List<XmlSecAlgorithm>>() {
- }));
+ POJOHelper.deserialize(signingSignatureAlgorithms, XMLSECAGO_TYPEREF));
}
if (signingSignatureReferenceDigestMethods != null) {
getSigningSignatureReferenceDigestMethods().addAll(
- POJOHelper.deserialize(signingSignatureReferenceDigestMethods,
- new TypeReference<List<XmlSecAlgorithm>>() {
- }));
+ POJOHelper.deserialize(signingSignatureReferenceDigestMethods, XMLSECAGO_TYPEREF));
}
if (encryptionDataAlgorithms != null) {
getEncryptionDataAlgorithms().addAll(
- POJOHelper.deserialize(encryptionDataAlgorithms,
- new TypeReference<List<XmlSecAlgorithm>>() {
- }));
+ POJOHelper.deserialize(encryptionDataAlgorithms, XMLSECAGO_TYPEREF));
}
if (encryptionKeyAlgorithms != null) {
getEncryptionKeyAlgorithms().addAll(
- POJOHelper.deserialize(encryptionKeyAlgorithms,
- new TypeReference<List<XmlSecAlgorithm>>() {
- }));
+ POJOHelper.deserialize(encryptionKeyAlgorithms, XMLSECAGO_TYPEREF));
}
if (signingSignatureBlackListedAlgorithms != null) {
getSigningSignatureBlackListedAlgorithms().addAll(
- POJOHelper.deserialize(signingSignatureBlackListedAlgorithms,
- new TypeReference<List<XmlSecAlgorithm>>() {
- }));
+ POJOHelper.deserialize(signingSignatureBlackListedAlgorithms, XMLSECAGO_TYPEREF));
}
if (encryptionBlackListedAlgorithms != null) {
getEncryptionBlackListedAlgorithms().addAll(
- POJOHelper.deserialize(encryptionBlackListedAlgorithms,
- new TypeReference<List<XmlSecAlgorithm>>() {
- }));
+ POJOHelper.deserialize(encryptionBlackListedAlgorithms, XMLSECAGO_TYPEREF));
}
}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAWAConfigEntry.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAWAConfigEntry.java
index 4b5c4cd6fc..eea214c74d 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAWAConfigEntry.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAWAConfigEntry.java
@@ -31,9 +31,12 @@ import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
@Table(name = JPAWAConfigEntry.TABLE)
public class JPAWAConfigEntry extends AbstractProvidedKeyEntity implements WAConfigEntry {
+ private static final long serialVersionUID = 6422422526695279794L;
+
public static final String TABLE = "WAConfigEntry";
- private static final long serialVersionUID = 6422422526695279794L;
+ protected static TypeReference<List<String>> TYPEREF = new TypeReference<List<String>>() {
+ };
@Lob
private String waConfigValues;
@@ -42,8 +45,7 @@ public class JPAWAConfigEntry extends AbstractProvidedKeyEntity implements WACon
public List<String> getValues() {
return waConfigValues == null
? List.of()
- : POJOHelper.deserialize(waConfigValues, new TypeReference<>() {
- });
+ : POJOHelper.deserialize(waConfigValues, TYPEREF);
}
@Override
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAMacroTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAMacroTask.java
new file mode 100644
index 0000000000..20fdcc5269
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAMacroTask.java
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.entity.task;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.Lob;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.PostLoad;
+import javax.persistence.PostPersist;
+import javax.persistence.PostUpdate;
+import javax.persistence.PrePersist;
+import javax.persistence.PreUpdate;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+import javax.persistence.UniqueConstraint;
+import javax.validation.constraints.NotNull;
+import org.apache.syncope.common.lib.command.CommandArgs;
+import org.apache.syncope.common.lib.types.IdRepoImplementationType;
+import org.apache.syncope.core.persistence.api.entity.Implementation;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.api.entity.task.MacroTask;
+import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
+import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
+import org.apache.syncope.core.persistence.jpa.entity.JPAImplementation;
+import org.apache.syncope.core.persistence.jpa.entity.JPARealm;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
+
+@Entity
+@Table(name = JPAMacroTask.TABLE)
+public class JPAMacroTask extends JPASchedTask implements MacroTask {
+
+ private static final long serialVersionUID = 8261850094316787406L;
+
+ public static final String TABLE = "MacroTask";
+
+ protected static final TypeReference<List<CommandArgs>> TYPEREF = new TypeReference<List<CommandArgs>>() {
+ };
+
+ @ManyToOne(fetch = FetchType.EAGER, optional = false)
+ private JPARealm realm;
+
+ @NotNull
+ private Boolean continueOnError = false;
+
+ @NotNull
+ private Boolean saveExecs = true;
+
+ @ManyToMany(fetch = FetchType.EAGER)
+ @JoinTable(name = TABLE + "Commands",
+ joinColumns =
+ @JoinColumn(name = "task_id"),
+ inverseJoinColumns =
+ @JoinColumn(name = "implementation_id"),
+ uniqueConstraints =
+ @UniqueConstraint(columnNames = { "task_id", "implementation_id" }))
+ private List<JPAImplementation> commands = new ArrayList<>();
+
+ @Lob
+ private String commandArgs;
+
+ @Transient
+ private final List<CommandArgs> commandArgsList = new ArrayList<>();
+
+ @OneToMany(targetEntity = JPAMacroTaskExec.class,
+ cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "task")
+ private List<TaskExec<SchedTask>> executions = new ArrayList<>();
+
+ @Override
+ public Realm getRealm() {
+ return realm;
+ }
+
+ @Override
+ public void setRealm(final Realm realm) {
+ checkType(realm, JPARealm.class);
+ this.realm = (JPARealm) realm;
+ }
+
+ @Override
+ public void add(final Implementation command, final CommandArgs args) {
+ checkType(command, JPAImplementation.class);
+ checkImplementationType(command, IdRepoImplementationType.COMMAND);
+ commands.add((JPAImplementation) command);
+
+ getCommandArgs().add(args);
+ }
+
+ @Override
+ public List<JPAImplementation> getCommands() {
+ return commands;
+ }
+
+ @Override
+ public List<CommandArgs> getCommandArgs() {
+ return commandArgsList;
+ }
+
+ @Override
+ public boolean isContinueOnError() {
+ return continueOnError == null ? false : continueOnError;
+ }
+
+ @Override
+ public void setContinueOnError(final boolean continueOnError) {
+ this.continueOnError = continueOnError;
+ }
+
+ @Override
+ public boolean isSaveExecs() {
+ return saveExecs == null ? true : saveExecs;
+ }
+
+ @Override
+ public void setSaveExecs(final boolean saveExecs) {
+ this.saveExecs = saveExecs;
+ }
+
+ @Override
+ protected Class<? extends TaskExec<SchedTask>> executionClass() {
+ return JPAMacroTaskExec.class;
+ }
+
+ @Override
+ protected List<TaskExec<SchedTask>> executions() {
+ return executions;
+ }
+
+ protected void json2list(final boolean clearFirst) {
+ if (clearFirst) {
+ getCommandArgs().clear();
+ }
+ if (commandArgs != null) {
+ getCommandArgs().addAll(POJOHelper.deserialize(commandArgs, TYPEREF));
+ }
+ }
+
+ @PostLoad
+ public void postLoad() {
+ json2list(false);
+ }
+
+ @PostPersist
+ @PostUpdate
+ public void postSave() {
+ json2list(true);
+ }
+
+ @PrePersist
+ @PreUpdate
+ public void list2json() {
+ commandArgs = POJOHelper.serialize(getCommandArgs(), TYPEREF);
+ }
+}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAMacroTaskExec.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAMacroTaskExec.java
new file mode 100644
index 0000000000..a0e877a08a
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAMacroTaskExec.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.entity.task;
+
+import javax.persistence.Entity;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.task.MacroTask;
+import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
+import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
+
+@Entity
+@Table(name = JPAMacroTaskExec.TABLE)
+public class JPAMacroTaskExec extends AbstractTaskExec<SchedTask> implements TaskExec<SchedTask> {
+
+ private static final long serialVersionUID = 1909033231464074554L;
+
+ public static final String TABLE = "MacroTaskExec";
+
+ @ManyToOne(optional = false)
+ private JPAMacroTask task;
+
+ @Override
+ public MacroTask getTask() {
+ return task;
+ }
+
+ @Override
+ public void setTask(final SchedTask task) {
+ checkType(task, MacroTask.class);
+ this.task = (JPAMacroTask) task;
+ }
+}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPANotificationTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPANotificationTask.java
index aeb7c5f137..995b98bb51 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPANotificationTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPANotificationTask.java
@@ -54,6 +54,9 @@ public class JPANotificationTask extends AbstractTask<NotificationTask> implemen
public static final String TABLE = "NotificationTask";
+ protected static final TypeReference<List<String>> TYPEREF = new TypeReference<List<String>>() {
+ };
+
@NotNull
@ManyToOne
private JPANotification notification;
@@ -205,9 +208,7 @@ public class JPANotificationTask extends AbstractTask<NotificationTask> implemen
getRecipients().clear();
}
if (recipients != null) {
- getRecipients().addAll(
- POJOHelper.deserialize(recipients, new TypeReference<List<String>>() {
- }));
+ getRecipients().addAll(POJOHelper.deserialize(recipients, TYPEREF));
}
}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASchedTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASchedTask.java
index aca10f3a64..cd680aedae 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASchedTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASchedTask.java
@@ -65,16 +65,6 @@ public class JPASchedTask extends AbstractTask<SchedTask> implements SchedTask {
cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "task")
private List<TaskExec<SchedTask>> executions = new ArrayList<>();
- @Override
- protected Class<? extends TaskExec<SchedTask>> executionClass() {
- return JPASchedTaskExec.class;
- }
-
- @Override
- protected List<TaskExec<SchedTask>> executions() {
- return executions;
- }
-
@Override
public Implementation getJobDelegate() {
return jobDelegate;
@@ -136,4 +126,14 @@ public class JPASchedTask extends AbstractTask<SchedTask> implements SchedTask {
public void setActive(final boolean active) {
this.active = active;
}
+
+ @Override
+ protected Class<? extends TaskExec<SchedTask>> executionClass() {
+ return JPASchedTaskExec.class;
+ }
+
+ @Override
+ protected List<TaskExec<SchedTask>> executions() {
+ return executions;
+ }
}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtils.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtils.java
index df6f3a8ad1..42276473fa 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtils.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtils.java
@@ -18,6 +18,7 @@
*/
package org.apache.syncope.core.persistence.jpa.entity.task;
+import org.apache.syncope.common.lib.to.MacroTaskTO;
import org.apache.syncope.common.lib.to.NotificationTaskTO;
import org.apache.syncope.common.lib.to.PropagationTaskTO;
import org.apache.syncope.common.lib.to.PullTaskTO;
@@ -25,24 +26,23 @@ import org.apache.syncope.common.lib.to.PushTaskTO;
import org.apache.syncope.common.lib.to.SchedTaskTO;
import org.apache.syncope.common.lib.to.TaskTO;
import org.apache.syncope.common.lib.types.TaskType;
-import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.task.MacroTask;
import org.apache.syncope.core.persistence.api.entity.task.NotificationTask;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.persistence.api.entity.task.PullTask;
import org.apache.syncope.core.persistence.api.entity.task.PushTask;
import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
import org.apache.syncope.core.persistence.api.entity.task.Task;
+import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
import org.apache.syncope.core.persistence.api.entity.task.TaskUtils;
+import org.apache.syncope.core.spring.security.SecureRandomUtils;
@SuppressWarnings("unchecked")
public final class JPATaskUtils implements TaskUtils {
- protected final EntityFactory entityFactory;
-
protected final TaskType type;
- protected JPATaskUtils(final EntityFactory entityFactory, final TaskType type) {
- this.entityFactory = entityFactory;
+ protected JPATaskUtils(final TaskType type) {
this.type = type;
}
@@ -72,6 +72,10 @@ public final class JPATaskUtils implements TaskUtils {
result = (Class<T>) PushTask.class;
break;
+ case MACRO:
+ result = (Class<T>) MacroTask.class;
+ break;
+
case NOTIFICATION:
result = (Class<T>) NotificationTask.class;
break;
@@ -88,26 +92,74 @@ public final class JPATaskUtils implements TaskUtils {
switch (type) {
case PROPAGATION:
- result = (T) entityFactory.newEntity(PropagationTask.class);
+ result = (T) new JPAPropagationTask();
break;
case SCHEDULED:
- result = (T) entityFactory.newEntity(SchedTask.class);
+ result = (T) new JPASchedTask();
break;
case PULL:
- result = (T) entityFactory.newEntity(PullTask.class);
+ result = (T) new JPAPullTask();
break;
case PUSH:
- result = (T) entityFactory.newEntity(PushTask.class);
+ result = (T) new JPAPushTask();
+ break;
+
+ case MACRO:
+ result = (T) new JPAMacroTask();
break;
case NOTIFICATION:
- result = (T) entityFactory.newEntity(NotificationTask.class);
+ result = (T) new JPANotificationTask();
+ break;
+
+ default:
+ }
+
+ if (result != null) {
+ ((AbstractTask<?>) result).setKey(SecureRandomUtils.generateRandomUUID().toString());
+ }
+
+ return result;
+ }
+
+ @Override
+ public <E extends TaskExec<?>> E newTaskExec() {
+ E result;
+
+ switch (type) {
+ case NOTIFICATION:
+ result = (E) new JPANotificationTaskExec();
+ break;
+
+ case PROPAGATION:
+ result = (E) new JPAPropagationTaskExec();
+ break;
+
+ case PULL:
+ result = (E) new JPAPullTaskExec();
+ break;
+
+ case PUSH:
+ result = (E) new JPAPushTaskExec();
+ break;
+
+ case MACRO:
+ result = (E) new JPAMacroTaskExec();
+ break;
+
+ case SCHEDULED:
+ result = (E) new JPASchedTaskExec();
break;
default:
+ result = null;
+ }
+
+ if (result != null) {
+ ((AbstractTaskExec<?>) result).setKey(SecureRandomUtils.generateRandomUUID().toString());
}
return result;
@@ -134,6 +186,10 @@ public final class JPATaskUtils implements TaskUtils {
result = (Class<T>) PushTaskTO.class;
break;
+ case MACRO:
+ result = (Class<T>) MacroTaskTO.class;
+ break;
+
case NOTIFICATION:
result = (Class<T>) NotificationTaskTO.class;
break;
@@ -153,4 +209,144 @@ public final class JPATaskUtils implements TaskUtils {
return null;
}
}
+
+ @Override
+ public String getTaskTable() {
+ String result = null;
+
+ switch (type) {
+ case NOTIFICATION:
+ result = JPANotificationTask.TABLE;
+ break;
+
+ case PROPAGATION:
+ result = JPAPropagationTask.TABLE;
+ break;
+
+ case PUSH:
+ result = JPAPushTask.TABLE;
+ break;
+
+ case PULL:
+ result = JPAPullTask.TABLE;
+ break;
+
+ case MACRO:
+ result = JPAMacroTask.TABLE;
+ break;
+
+ case SCHEDULED:
+ result = JPASchedTask.TABLE;
+ break;
+
+ default:
+ }
+
+ return result;
+ }
+
+ @Override
+ public Class<? extends Task<?>> getTaskEntity() {
+ Class<? extends Task<?>> result = null;
+
+ switch (type) {
+ case NOTIFICATION:
+ result = JPANotificationTask.class;
+ break;
+
+ case PROPAGATION:
+ result = JPAPropagationTask.class;
+ break;
+
+ case PUSH:
+ result = JPAPushTask.class;
+ break;
+
+ case PULL:
+ result = JPAPullTask.class;
+ break;
+
+ case MACRO:
+ result = JPAMacroTask.class;
+ break;
+
+ case SCHEDULED:
+ result = JPASchedTask.class;
+ break;
+
+ default:
+ }
+
+ return result;
+ }
+
+ @Override
+ public String getTaskExecTable() {
+ String result = null;
+
+ switch (type) {
+ case NOTIFICATION:
+ result = JPANotificationTaskExec.TABLE;
+ break;
+
+ case PROPAGATION:
+ result = JPAPropagationTaskExec.TABLE;
+ break;
+
+ case SCHEDULED:
+ result = JPASchedTaskExec.TABLE;
+ break;
+
+ case PUSH:
+ result = JPAPushTaskExec.TABLE;
+ break;
+
+ case PULL:
+ result = JPAPullTaskExec.TABLE;
+ break;
+
+ case MACRO:
+ result = JPAMacroTaskExec.TABLE;
+ break;
+
+ default:
+ }
+
+ return result;
+ }
+
+ @Override
+ public Class<? extends TaskExec<?>> getTaskExecEntity() {
+ Class<? extends TaskExec<?>> result = null;
+
+ switch (type) {
+ case NOTIFICATION:
+ result = JPANotificationTaskExec.class;
+ break;
+
+ case PROPAGATION:
+ result = JPAPropagationTaskExec.class;
+ break;
+
+ case SCHEDULED:
+ result = JPASchedTaskExec.class;
+ break;
+
+ case PUSH:
+ result = JPAPushTaskExec.class;
+ break;
+
+ case PULL:
+ result = JPAPullTaskExec.class;
+ break;
+
+ case MACRO:
+ result = JPAMacroTaskExec.class;
+ break;
+
+ default:
+ }
+
+ return result;
+ }
}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtilsFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtilsFactory.java
index 53c9575641..35cce33c29 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtilsFactory.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtilsFactory.java
@@ -20,6 +20,7 @@ package org.apache.syncope.core.persistence.jpa.entity.task;
import java.util.HashMap;
import java.util.Map;
+import org.apache.syncope.common.lib.to.MacroTaskTO;
import org.apache.syncope.common.lib.to.NotificationTaskTO;
import org.apache.syncope.common.lib.to.PropagationTaskTO;
import org.apache.syncope.common.lib.to.PullTaskTO;
@@ -27,7 +28,7 @@ import org.apache.syncope.common.lib.to.PushTaskTO;
import org.apache.syncope.common.lib.to.SchedTaskTO;
import org.apache.syncope.common.lib.to.TaskTO;
import org.apache.syncope.common.lib.types.TaskType;
-import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.task.MacroTask;
import org.apache.syncope.core.persistence.api.entity.task.NotificationTask;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.persistence.api.entity.task.PullTask;
@@ -40,21 +41,15 @@ import org.apache.syncope.core.spring.ApplicationContextProvider;
public class JPATaskUtilsFactory implements TaskUtilsFactory {
- protected final EntityFactory entityFactory;
-
protected final Map<TaskType, TaskUtils> instances = new HashMap<>(5);
- public JPATaskUtilsFactory(final EntityFactory entityFactory) {
- this.entityFactory = entityFactory;
- }
-
@Override
public TaskUtils getInstance(final TaskType type) {
TaskUtils instance;
synchronized (instances) {
instance = instances.get(type);
if (instance == null) {
- instance = new JPATaskUtils(entityFactory, type);
+ instance = new JPATaskUtils(type);
ApplicationContextProvider.getBeanFactory().autowireBean(instance);
instances.put(type, instance);
}
@@ -70,6 +65,8 @@ public class JPATaskUtilsFactory implements TaskUtilsFactory {
type = TaskType.PULL;
} else if (task instanceof PushTask) {
type = TaskType.PUSH;
+ } else if (task instanceof MacroTask) {
+ type = TaskType.MACRO;
} else if (task instanceof SchedTask) {
type = TaskType.SCHEDULED;
} else if (task instanceof PropagationTask) {
@@ -96,6 +93,8 @@ public class JPATaskUtilsFactory implements TaskUtilsFactory {
type = TaskType.PULL;
} else if (taskClass == PushTaskTO.class) {
type = TaskType.PUSH;
+ } else if (taskClass == MacroTaskTO.class) {
+ type = TaskType.MACRO;
} else {
throw new IllegalArgumentException("Invalid TaskTO class: " + taskClass.getName());
}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
index 28fad86e1d..abd9b71e6f 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
@@ -78,13 +78,16 @@ public class JPAUser
public static final String TABLE = "SyncopeUser";
- private static final Encryptor ENCRYPTOR = Encryptor.getInstance();
+ protected static final Encryptor ENCRYPTOR = Encryptor.getInstance();
+
+ protected static final TypeReference<List<String>> TYPEREF = new TypeReference<List<String>>() {
+ };
@Column(nullable = true)
- private String password;
+ protected String password;
@Transient
- private String clearPassword;
+ protected String clearPassword;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(joinColumns =
@@ -93,53 +96,53 @@ public class JPAUser
@JoinColumn(name = "role_id"),
uniqueConstraints =
@UniqueConstraint(columnNames = { "user_id", "role_id" }))
- private List<JPARole> roles = new ArrayList<>();
+ protected List<JPARole> roles = new ArrayList<>();
@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
@Valid
- private List<JPAUPlainAttr> plainAttrs = new ArrayList<>();
+ protected List<JPAUPlainAttr> plainAttrs = new ArrayList<>();
@Column(nullable = true)
- private String status;
+ protected String status;
@Lob
- private String token;
+ protected String token;
- private OffsetDateTime tokenExpireTime;
+ protected OffsetDateTime tokenExpireTime;
@Column(nullable = true)
@Enumerated(EnumType.STRING)
- private CipherAlgorithm cipherAlgorithm;
+ protected CipherAlgorithm cipherAlgorithm;
@Lob
- private String passwordHistory;
+ protected String passwordHistory;
/**
* Subsequent failed logins.
*/
@Column(nullable = true)
- private Integer failedLogins;
+ protected Integer failedLogins;
/**
* Username/Login.
*/
@Column(unique = true)
@NotNull(message = "Blank username")
- private String username;
+ protected String username;
/**
* Last successful login date.
*/
- private OffsetDateTime lastLoginDate;
+ protected OffsetDateTime lastLoginDate;
/**
* Change password date.
*/
- private OffsetDateTime changePwdDate;
+ protected OffsetDateTime changePwdDate;
- private Boolean suspended = false;
+ protected Boolean suspended = false;
- private Boolean mustChangePassword = false;
... 2301 lines suppressed ...