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 2015/07/07 09:38:01 UTC
[7/7] syncope git commit: [SYNCOPE-676] Merge from 1_2_X
[SYNCOPE-676] Merge from 1_2_X
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/97607b16
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/97607b16
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/97607b16
Branch: refs/heads/master
Commit: 97607b16e4ed807ff055b3ae55f0c722717c6472
Parents: 3eb0bfb 2612337
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Tue Jul 7 09:37:35 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Tue Jul 7 09:37:35 2015 +0200
----------------------------------------------------------------------
.../client/console/commons/Constants.java | 2 -
.../client/console/rest/GroupRestClient.java | 4 +-
.../client/console/rest/UserRestClient.java | 4 +-
.../lib/builders/AnyListQueryBuilder.java | 6 ++
.../lib/builders/AnySearchQueryBuilder.java | 6 ++
.../client/lib/builders/ListQueryBuilder.java | 6 ++
.../pages/DisplayAttributesModalPage.java | 48 +----------
.../console/panels/UserSearchResultPanel.java | 11 +--
.../client/console/rest/UserRestClient.java | 4 +-
.../pages/DisplayAttributesModalPage.html | 2 -
.../common/rest/api/beans/ListQuery.java | 12 +++
.../common/rest/api/service/JAXRSService.java | 2 +
.../syncope/core/logic/AbstractAnyLogic.java | 10 ++-
.../syncope/core/logic/AnyObjectLogic.java | 16 ++--
.../apache/syncope/core/logic/GroupLogic.java | 13 +--
.../apache/syncope/core/logic/UserLogic.java | 13 +--
.../core/logic/report/GroupReportlet.java | 2 +-
.../core/logic/report/UserReportlet.java | 7 +-
.../syncope/core/logic/NotificationTest.java | 7 +-
.../src/main/resources/indexes.xml | 31 ++++++++
.../api/data/AnyObjectDataBinder.java | 2 +-
.../provisioning/api/data/GroupDataBinder.java | 2 +-
.../provisioning/api/data/UserDataBinder.java | 2 +-
.../java/data/AnyObjectDataBinderImpl.java | 53 +++++++------
.../java/data/GroupDataBinderImpl.java | 10 ++-
.../java/data/UserDataBinderImpl.java | 83 +++++++++++---------
.../notification/NotificationManagerImpl.java | 6 +-
.../sync/AnyObjectPushResultHandlerImpl.java | 4 +-
.../java/sync/GroupPushResultHandlerImpl.java | 4 +-
.../rest/cxf/service/AbstractAnyService.java | 6 +-
.../rest/cxf/service/AbstractServiceImpl.java | 3 -
.../rest/cxf/service/AnyObjectServiceImpl.java | 3 +-
.../activiti/ActivitiUserWorkflowAdapter.java | 4 +-
.../fit/console/reference/ReportITCase.java | 4 +-
34 files changed, 212 insertions(+), 180 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/97607b16/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java
----------------------------------------------------------------------
diff --cc client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java
index 0b8391a,0000000..98339ec
mode 100644,000000..100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java
@@@ -1,110 -1,0 +1,108 @@@
+/*
+ * 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.commons;
+
+public final class Constants {
+
+ public static final String ON_CLICK = "onclick";
+
+ public static final String ON_CHANGE = "onchange";
+
+ public static final String ON_BLUR = "onblur";
+
+ public static final String PNG_EXT = ".png";
+
+ public static final String FEEDBACK = "feedback";
+
+ public static final String OPERATION_SUCCEEDED = "operation_succeeded";
+
+ public static final String OPERATION_ERROR = "operation_error";
+
+ public static final String SEARCH_ERROR = "search_error";
+
+ public static final String ERROR = "error";
+
+ public static final String PARAM_PASSWORD_RESET_TOKEN = "pwdResetToken";
+
+ public static final String PREF_USERS_DETAILS_VIEW = "users.details.view";
+
+ public static final String PREF_USERS_ATTRIBUTES_VIEW = "users.attributes.view";
+
+ public static final String PREF_USERS_DERIVED_ATTRIBUTES_VIEW = "users.derived.attributes.view";
+
- public static final String PREF_USERS_VIRTUAL_ATTRIBUTES_VIEW = "users.virtual.attributes.view";
-
+ public static final String PREF_CONF_SCHEMA_PAGINATOR_ROWS = "conf.schema.paginator.rows";
+
+ public static final String PREF_USER_PLAIN_SCHEMA_PAGINATOR_ROWS = "user.schema.paginator.rows";
+
+ public static final String PREF_USER_DER_SCHEMA_PAGINATOR_ROWS = "user.derived.schema.paginator.rows";
+
+ public static final String PREF_USER_VIR_SCHEMA_PAGINATOR_ROWS = "user.virtual.schema.paginator.rows";
+
+ public static final String PREF_GROUP_PLAIN_SCHEMA_PAGINATOR_ROWS = "group.schema.paginator.rows";
+
+ public static final String PREF_GROUP_DER_SCHEMA_PAGINATOR_ROWS = "group.derived.schema.paginator.rows";
+
+ public static final String PREF_GROUP_VIR_SCHEMA_PAGINATOR_ROWS = "group.virtual.schema.paginator.rows";
+
+ public static final String PREF_MEMBERSHIP_PLAIN_SCHEMA_PAGINATOR_ROWS = "membership.schema.paginator.rows";
+
+ public static final String PREF_MEMBERSHIP_DER_SCHEMA_PAGINATOR_ROWS = "membership.derived.aschema.paginator.rows";
+
+ public static final String PREF_MEMBERSHIP_VIR_SCHEMA_PAGINATOR_ROWS = "membership.virtual.aschema.paginator.rows";
+
+ public static final String PREF_USERS_PAGINATOR_ROWS = "users.paginator.rows";
+
+ public static final String PREF_RESOURCES_PAGINATOR_ROWS = "resources.paginator.rows";
+
+ public static final String PREF_CONNECTORS_PAGINATOR_ROWS = "connectors.paginator.rows";
+
+ public static final String PREF_NOTIFICATION_PAGINATOR_ROWS = "notification.paginator.rows";
+
+ public static final String PREF_PROPAGATION_TASKS_PAGINATOR_ROWS = "proagationtasks.paginator.rows";
+
+ public static final String PREF_NOTIFICATION_TASKS_PAGINATOR_ROWS = "notificationtasks.paginator.rows";
+
+ public static final String PREF_SCHED_TASKS_PAGINATOR_ROWS = "schedtasks.paginator.rows";
+
+ public static final String PREF_SYNC_TASKS_PAGINATOR_ROWS = "synctasks.paginator.rows";
+
+ public static final String PREF_TODO_PAGINATOR_ROWS = "todo.paginator.rows";
+
+ public static final String PREF_REPORT_PAGINATOR_ROWS = "report.paginator.rows";
+
+ public static final String PAGEPARAM_CREATE = "CREATE";
+
+ public static final String PAGEPARAM_CURRENT_PAGE = "_current_page";
+
+ public static final String PREF_POLICY_PAGINATOR_ROWS = "policy.paginator.rows";
+
+ /**
+ * ConnId's GuardedString is not in the classpath.
+ */
+ public static final String GUARDED_STRING = "org.identityconnectors.common.security.GuardedString";
+
+ /**
+ * ConnId's GuardedByteArray is not in the classpath.
+ */
+ public static final String GUARDED_BYTE_ARRAY = "org.identityconnectors.common.security.GuardedByteArray";
+
+ private Constants() {
+ // private constructor for static utility class
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/97607b16/client/console/src/main/java/org/apache/syncope/client/console/rest/GroupRestClient.java
----------------------------------------------------------------------
diff --cc client/console/src/main/java/org/apache/syncope/client/console/rest/GroupRestClient.java
index b4b848c,0000000..512e08f
mode 100644,000000..100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/GroupRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/GroupRestClient.java
@@@ -1,204 -1,0 +1,204 @@@
+/*
+ * 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 javax.ws.rs.core.Response;
+import org.apache.syncope.client.console.commons.status.StatusBean;
+import org.apache.syncope.client.console.commons.status.StatusUtils;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.mod.GroupMod;
+import org.apache.syncope.common.lib.mod.ResourceAssociationMod;
+import org.apache.syncope.common.lib.to.BulkAction;
+import org.apache.syncope.common.lib.to.BulkActionResult;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
+import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
+import org.apache.syncope.common.lib.wrap.ResourceKey;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
+import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.apache.syncope.common.rest.api.service.GroupService;
+import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
+import org.springframework.stereotype.Component;
+
+/**
+ * Console client for invoking Rest Group's services.
+ */
+@Component
+public class GroupRestClient extends AbstractAnyRestClient {
+
+ private static final long serialVersionUID = -8549081557283519638L;
+
+ @Override
+ public int count(final String realm) {
+ return getService(GroupService.class).
+ list(SyncopeClient.getAnyListQueryBuilder().realm(realm).page(1).size(1).build()).
+ getTotalCount();
+ }
+
+ @Override
+ public List<GroupTO> list(final String realm, final int page, final int size, final SortParam<String> sort) {
+ return getService(GroupService.class).
+ list(SyncopeClient.getAnyListQueryBuilder().realm(realm).page(page).size(size).
- orderBy(toOrderBy(sort)).build()).
++ orderBy(toOrderBy(sort)).details(false).build()).
+ getResult();
+ }
+
+ @Override
+ public int searchCount(final String realm, final String fiql) {
+ return getService(GroupService.class).
+ search(SyncopeClient.getAnySearchQueryBuilder().realm(realm).fiql(fiql).page(1).size(1).build()).
+ getTotalCount();
+ }
+
+ @Override
+ public List<GroupTO> search(
+ final String realm, final String fiql, final int page, final int size, final SortParam<String> sort) {
+
+ return getService(GroupService.class).
+ search(SyncopeClient.getAnySearchQueryBuilder().realm(realm).fiql(fiql).page(page).size(size).
- orderBy(toOrderBy(sort)).build()).
++ orderBy(toOrderBy(sort)).details(false).build()).
+ getResult();
+ }
+
+ @Override
+ public ConnObjectTO readConnObject(final String resourceName, final Long id) {
+ return getService(ResourceService.class).readConnObject(resourceName, AnyTypeKind.GROUP.name(), id);
+ }
+
+ public GroupTO create(final GroupTO groupTO) {
+ Response response = getService(GroupService.class).create(groupTO);
+ return response.readEntity(GroupTO.class);
+ }
+
+ public GroupTO read(final Long key) {
+ return getService(GroupService.class).read(key);
+ }
+
+ public GroupTO update(final String etag, final GroupMod groupMod) {
+ GroupTO result;
+ synchronized (this) {
+ GroupService service = getService(etag, GroupService.class);
+ result = service.update(groupMod).readEntity(GroupTO.class);
+ resetClient(GroupService.class);
+ }
+ return result;
+ }
+
+ @Override
+ public GroupTO delete(final String etag, final Long key) {
+ GroupTO result;
+ synchronized (this) {
+ GroupService service = getService(etag, GroupService.class);
+ result = service.delete(key).readEntity(GroupTO.class);
+ resetClient(GroupService.class);
+ }
+ return result;
+ }
+
+ @Override
+ public BulkActionResult bulkAction(final BulkAction action) {
+ return getService(GroupService.class).bulk(action);
+ }
+
+ public void unlink(final String etag, final long groupKey, final List<StatusBean> statuses) {
+ synchronized (this) {
+ GroupService service = getService(etag, GroupService.class);
+ service.bulkDeassociation(groupKey, ResourceDeassociationActionType.UNLINK,
+ CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
+ ResourceKey.class));
+ resetClient(GroupService.class);
+ }
+ }
+
+ public void link(final String etag, final long groupKey, final List<StatusBean> statuses) {
+ synchronized (this) {
+ GroupService service = getService(etag, GroupService.class);
+
+ ResourceAssociationMod associationMod = new ResourceAssociationMod();
+ associationMod.getTargetResources().addAll(
+ CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(), ResourceKey.class));
+ service.bulkAssociation(groupKey, ResourceAssociationActionType.LINK, associationMod);
+
+ resetClient(GroupService.class);
+ }
+ }
+
+ public BulkActionResult deprovision(final String etag, final long groupKey, final List<StatusBean> statuses) {
+ BulkActionResult result;
+ synchronized (this) {
+ GroupService service = getService(etag, GroupService.class);
+ result = service.bulkDeassociation(groupKey, ResourceDeassociationActionType.DEPROVISION,
+ CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
+ ResourceKey.class)).
+ readEntity(BulkActionResult.class);
+ resetClient(GroupService.class);
+ }
+ return result;
+ }
+
+ public BulkActionResult provision(final String etag, final long groupKey, final List<StatusBean> statuses) {
+ BulkActionResult result;
+ synchronized (this) {
+ GroupService service = getService(etag, GroupService.class);
+
+ ResourceAssociationMod associationMod = new ResourceAssociationMod();
+ associationMod.getTargetResources().addAll(
+ CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(), ResourceKey.class));
+
+ result = service.bulkAssociation(groupKey, ResourceAssociationActionType.PROVISION, associationMod).
+ readEntity(BulkActionResult.class);
+ resetClient(GroupService.class);
+ }
+ return result;
+ }
+
+ public BulkActionResult unassign(final String etag, final long groupKey, final List<StatusBean> statuses) {
+ BulkActionResult result;
+ synchronized (this) {
+ GroupService service = getService(etag, GroupService.class);
+ result = service.bulkDeassociation(groupKey, ResourceDeassociationActionType.UNASSIGN,
+ CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
+ ResourceKey.class)).
+ readEntity(BulkActionResult.class);
+ resetClient(GroupService.class);
+ }
+ return result;
+ }
+
+ public BulkActionResult assign(final String etag, final long groupKey, final List<StatusBean> statuses) {
+ BulkActionResult result;
+ synchronized (this) {
+ GroupService service = getService(etag, GroupService.class);
+
+ ResourceAssociationMod associationMod = new ResourceAssociationMod();
+ associationMod.getTargetResources().addAll(
+ CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(), ResourceKey.class));
+
+ result = service.bulkAssociation(groupKey, ResourceAssociationActionType.ASSIGN, associationMod).
+ readEntity(BulkActionResult.class);
+
+ resetClient(GroupService.class);
+ }
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/97607b16/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
----------------------------------------------------------------------
diff --cc client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
index f517c4c,0000000..338851d
mode 100644,000000..100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
@@@ -1,238 -1,0 +1,238 @@@
+/*
+ * 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 javax.ws.rs.core.Response;
+import org.apache.syncope.client.console.commons.status.StatusBean;
+import org.apache.syncope.client.console.commons.status.StatusUtils;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.mod.ResourceAssociationMod;
+import org.apache.syncope.common.lib.mod.StatusMod;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.common.lib.to.BulkAction;
+import org.apache.syncope.common.lib.to.BulkActionResult;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
+import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
+import org.apache.syncope.common.lib.wrap.ResourceKey;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
+import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.apache.syncope.common.rest.api.service.UserService;
+import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
+import org.springframework.stereotype.Component;
+
+/**
+ * Console client for invoking rest users services.
+ */
+@Component
+public class UserRestClient extends AbstractAnyRestClient {
+
+ private static final long serialVersionUID = -1575748964398293968L;
+
+ @Override
+ public int count(final String realm) {
+ return getService(UserService.class).
+ list(SyncopeClient.getAnyListQueryBuilder().realm(realm).page(1).size(1).build()).
+ getTotalCount();
+ }
+
+ @Override
+ public List<UserTO> list(final String realm, final int page, final int size, final SortParam<String> sort) {
+ return getService(UserService.class).
+ list(SyncopeClient.getAnyListQueryBuilder().realm(realm).page(page).size(size).
- orderBy(toOrderBy(sort)).build()).
++ orderBy(toOrderBy(sort)).details(false).build()).
+ getResult();
+ }
+
+ public UserTO create(final UserTO userTO, final boolean storePassword) {
+ Response response = getService(UserService.class).create(userTO, storePassword);
+ return response.readEntity(UserTO.class);
+ }
+
+ public UserTO update(final String etag, final UserMod userMod) {
+ UserTO result;
+ synchronized (this) {
+ UserService service = getService(etag, UserService.class);
+ result = service.update(userMod).readEntity(UserTO.class);
+ resetClient(UserService.class);
+ }
+ return result;
+ }
+
+ @Override
+ public UserTO delete(final String etag, final Long id) {
+ UserTO result;
+ synchronized (this) {
+ UserService service = getService(etag, UserService.class);
+ result = service.delete(id).readEntity(UserTO.class);
+ resetClient(UserService.class);
+ }
+ return result;
+ }
+
+ public UserTO read(final Long id) {
+ UserTO userTO = null;
+ try {
+ userTO = getService(UserService.class).read(id);
+ } catch (SyncopeClientException e) {
+ LOG.error("While reading a user", e);
+ }
+ return userTO;
+ }
+
+ @Override
+ public int searchCount(final String realm, final String fiql) {
+ return getService(UserService.class).
+ search(SyncopeClient.getAnySearchQueryBuilder().realm(realm).fiql(fiql).page(1).size(1).build()).
+ getTotalCount();
+ }
+
+ @Override
+ public List<UserTO> search(
+ final String realm, final String fiql, final int page, final int size, final SortParam<String> sort) {
+
+ return getService(UserService.class).
+ search(SyncopeClient.getAnySearchQueryBuilder().realm(realm).fiql(fiql).page(page).size(size).
- orderBy(toOrderBy(sort)).build()).
++ orderBy(toOrderBy(sort)).details(false).build()).
+ getResult();
+ }
+
+ @Override
+ public ConnObjectTO readConnObject(final String resourceName, final Long id) {
+ return getService(ResourceService.class).readConnObject(resourceName, AnyTypeKind.USER.name(), id);
+ }
+
+ public void suspend(final String etag, final long userKey, final List<StatusBean> statuses) {
+ StatusMod statusMod = StatusUtils.buildStatusMod(statuses, false);
+ statusMod.setType(StatusMod.ModType.SUSPEND);
+ synchronized (this) {
+ UserService service = getService(etag, UserService.class);
+ service.status(userKey, statusMod);
+ resetClient(UserService.class);
+ }
+ }
+
+ public void reactivate(final String etag, final long userKey, final List<StatusBean> statuses) {
+ StatusMod statusMod = StatusUtils.buildStatusMod(statuses, true);
+ statusMod.setType(StatusMod.ModType.REACTIVATE);
+ synchronized (this) {
+ UserService service = getService(etag, UserService.class);
+ service.status(userKey, statusMod);
+ resetClient(UserService.class);
+ }
+ }
+
+ @Override
+ public BulkActionResult bulkAction(final BulkAction action) {
+ return getService(UserService.class).bulk(action);
+ }
+
+ public void unlink(final String etag, final long userKey, final List<StatusBean> statuses) {
+ synchronized (this) {
+ UserService service = getService(etag, UserService.class);
+ service.bulkDeassociation(userKey, ResourceDeassociationActionType.UNLINK,
+ CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
+ ResourceKey.class));
+ resetClient(UserService.class);
+ }
+ }
+
+ public void link(final String etag, final long userKey, final List<StatusBean> statuses) {
+ synchronized (this) {
+ UserService service = getService(etag, UserService.class);
+
+ ResourceAssociationMod associationMod = new ResourceAssociationMod();
+ associationMod.getTargetResources().addAll(
+ CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(), ResourceKey.class));
+ service.bulkAssociation(userKey, ResourceAssociationActionType.LINK, associationMod);
+
+ resetClient(UserService.class);
+ }
+ }
+
+ public BulkActionResult deprovision(final String etag, final long userKey, final List<StatusBean> statuses) {
+ BulkActionResult result;
+ synchronized (this) {
+ UserService service = getService(etag, UserService.class);
+ result = service.bulkDeassociation(userKey, ResourceDeassociationActionType.DEPROVISION,
+ CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
+ ResourceKey.class)).
+ readEntity(BulkActionResult.class);
+ resetClient(UserService.class);
+ }
+ return result;
+ }
+
+ public BulkActionResult provision(final String etag, final long userKey,
+ final List<StatusBean> statuses, final boolean changepwd, final String password) {
+
+ BulkActionResult result;
+ synchronized (this) {
+ UserService service = getService(etag, UserService.class);
+
+ ResourceAssociationMod associationMod = new ResourceAssociationMod();
+ associationMod.getTargetResources().addAll(
+ CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(), ResourceKey.class));
+ associationMod.setChangePwd(changepwd);
+ associationMod.setPassword(password);
+
+ result = service.bulkAssociation(userKey, ResourceAssociationActionType.PROVISION, associationMod).
+ readEntity(BulkActionResult.class);
+ resetClient(UserService.class);
+ }
+ return result;
+ }
+
+ public BulkActionResult unassign(final String etag, final long userKey, final List<StatusBean> statuses) {
+ BulkActionResult result;
+ synchronized (this) {
+ UserService service = getService(etag, UserService.class);
+ result = service.bulkDeassociation(userKey, ResourceDeassociationActionType.UNASSIGN,
+ CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
+ ResourceKey.class)).
+ readEntity(BulkActionResult.class);
+ resetClient(UserService.class);
+ }
+ return result;
+ }
+
+ public BulkActionResult assign(final String etag, final long userKey,
+ final List<StatusBean> statuses, final boolean changepwd, final String password) {
+
+ BulkActionResult result;
+ synchronized (this) {
+ UserService service = getService(etag, UserService.class);
+
+ ResourceAssociationMod associationMod = new ResourceAssociationMod();
+ associationMod.getTargetResources().addAll(
+ CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(), ResourceKey.class));
+ associationMod.setChangePwd(changepwd);
+ associationMod.setPassword(password);
+
+ result = service.bulkAssociation(userKey, ResourceAssociationActionType.ASSIGN, associationMod).
+ readEntity(BulkActionResult.class);
+ resetClient(UserService.class);
+ }
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/97607b16/client/lib/src/main/java/org/apache/syncope/client/lib/builders/AnyListQueryBuilder.java
----------------------------------------------------------------------
diff --cc client/lib/src/main/java/org/apache/syncope/client/lib/builders/AnyListQueryBuilder.java
index afd29e9,0000000..e25daef
mode 100644,000000..100644
--- a/client/lib/src/main/java/org/apache/syncope/client/lib/builders/AnyListQueryBuilder.java
+++ b/client/lib/src/main/java/org/apache/syncope/client/lib/builders/AnyListQueryBuilder.java
@@@ -1,62 -1,0 +1,68 @@@
+/*
+ * 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.lib.builders;
+
+import java.util.ArrayList;
+import org.apache.syncope.common.rest.api.beans.ListQuery;
+import org.apache.syncope.common.rest.api.beans.AnyListQuery;
+
+public class AnyListQueryBuilder extends ListQueryBuilder {
+
+ private final AnyListQuery instance = new AnyListQuery();
+
+ @Override
+ public AnyListQueryBuilder page(final Integer page) {
+ return AnyListQueryBuilder.class.cast(super.page(page));
+ }
+
+ @Override
+ public AnyListQueryBuilder size(final Integer size) {
+ return AnyListQueryBuilder.class.cast(super.size(size));
+ }
+
+ @Override
+ public AnyListQueryBuilder orderBy(final String orderBy) {
+ return AnyListQueryBuilder.class.cast(super.orderBy(orderBy));
+ }
+
++ @Override
++ public AnyListQueryBuilder details(final boolean details) {
++ return AnyListQueryBuilder.class.cast(super.details(details));
++ }
++
+ public AnyListQueryBuilder realm(final String realm) {
+ if (instance.getRealms() == null) {
+ instance.setRealms(new ArrayList<String>());
+ }
+ instance.getRealms().add(realm);
+
+ return this;
+ }
+
+ @Override
+ public AnyListQuery build() {
+ ListQuery lq = super.build();
+ instance.setPage(lq.getPage());
+ instance.setSize(lq.getSize());
+ instance.setOrderBy(lq.getOrderBy());
++ instance.setDetails(lq.isDetails());
+
+ return instance;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/97607b16/client/lib/src/main/java/org/apache/syncope/client/lib/builders/AnySearchQueryBuilder.java
----------------------------------------------------------------------
diff --cc client/lib/src/main/java/org/apache/syncope/client/lib/builders/AnySearchQueryBuilder.java
index c3fce47,0000000..5bffdcc
mode 100644,000000..100644
--- a/client/lib/src/main/java/org/apache/syncope/client/lib/builders/AnySearchQueryBuilder.java
+++ b/client/lib/src/main/java/org/apache/syncope/client/lib/builders/AnySearchQueryBuilder.java
@@@ -1,64 -1,0 +1,70 @@@
+/*
+ * 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.lib.builders;
+
+import org.apache.syncope.common.rest.api.beans.AnyListQuery;
+import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
+
+public class AnySearchQueryBuilder extends AnyListQueryBuilder {
+
+ private final AnySearchQuery instance = new AnySearchQuery();
+
+ @Override
+ public AnySearchQueryBuilder realm(final String realm) {
+ return AnySearchQueryBuilder.class.cast(super.realm(realm));
+ }
+
+ @Override
+ public AnySearchQueryBuilder page(final Integer page) {
+ return AnySearchQueryBuilder.class.cast(super.page(page));
+ }
+
+ @Override
+ public AnySearchQueryBuilder size(final Integer size) {
+ return AnySearchQueryBuilder.class.cast(super.size(size));
+ }
+
+ @Override
+ public AnySearchQueryBuilder orderBy(final String orderBy) {
+ return AnySearchQueryBuilder.class.cast(super.orderBy(orderBy));
+ }
+
++ @Override
++ public AnySearchQueryBuilder details(final boolean details) {
++ return AnySearchQueryBuilder.class.cast(super.details(details));
++ }
++
+ public AnySearchQueryBuilder fiql(final String fiql) {
+ instance.setFiql(fiql);
+
+ return this;
+ }
+
+ @Override
+ public AnySearchQuery build() {
+ AnyListQuery slq = super.build();
+ instance.setRealms(slq.getRealms());
+ instance.setPage(slq.getPage());
+ instance.setSize(slq.getSize());
+ instance.setOrderBy(slq.getOrderBy());
++ instance.setDetails(slq.isDetails());
+
+ return instance;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/97607b16/client/lib/src/main/java/org/apache/syncope/client/lib/builders/ListQueryBuilder.java
----------------------------------------------------------------------
diff --cc client/lib/src/main/java/org/apache/syncope/client/lib/builders/ListQueryBuilder.java
index 5d6202a,0000000..bce0e73
mode 100644,000000..100644
--- a/client/lib/src/main/java/org/apache/syncope/client/lib/builders/ListQueryBuilder.java
+++ b/client/lib/src/main/java/org/apache/syncope/client/lib/builders/ListQueryBuilder.java
@@@ -1,48 -1,0 +1,54 @@@
+/*
+ * 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.lib.builders;
+
+import org.apache.syncope.common.rest.api.beans.ListQuery;
+
+public class ListQueryBuilder {
+
+ private final ListQuery instance = new ListQuery();
+
+ public ListQueryBuilder page(final Integer page) {
+ instance.setPage(page);
+
+ return this;
+ }
+
+ public ListQueryBuilder size(final Integer size) {
+ instance.setSize(size);
+
+ return this;
+ }
+
+ public ListQueryBuilder orderBy(final String orderBy) {
+ instance.setOrderBy(orderBy);
+
+ return this;
+ }
+
++ public ListQueryBuilder details(final boolean details) {
++ instance.setDetails(details);
++
++ return this;
++ }
++
+ public ListQuery build() {
+ return instance;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/97607b16/client/old_console/src/main/java/org/apache/syncope/client/console/pages/DisplayAttributesModalPage.java
----------------------------------------------------------------------
diff --cc client/old_console/src/main/java/org/apache/syncope/client/console/pages/DisplayAttributesModalPage.java
index 6f89ec3,0000000..d588a01
mode 100644,000000..100644
--- a/client/old_console/src/main/java/org/apache/syncope/client/console/pages/DisplayAttributesModalPage.java
+++ b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/DisplayAttributesModalPage.java
@@@ -1,273 -1,0 +1,231 @@@
+/*
+ * 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.pages;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.commons.PreferenceManager;
+import org.apache.syncope.common.lib.search.SearchableFields;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.Check;
+import org.apache.wicket.markup.html.form.CheckGroup;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.list.ListItem;
+import org.apache.wicket.markup.html.list.ListView;
+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.LoadableDetachableModel;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+
+/**
+ * Modal window with Display attributes form.
+ */
+@SuppressWarnings({ "unchecked", "rawtypes" })
+public class DisplayAttributesModalPage extends BaseModalPage {
+
+ private static final long serialVersionUID = -4274117450918385110L;
+
+ /**
+ * Max allowed selections.
+ */
+ private static final int MAX_SELECTIONS = 9;
+
+ public static final String[] DEFAULT_SELECTION = { "key", "username", "status" };
+
+ @SpringBean
+ private PreferenceManager prefMan;
+
+ private final List<String> selectedDetails;
+
+ private final List<String> selectedPlainSchemas;
+
+ private final List<String> selectedDerSchemas;
+
- private final List<String> selectedVirSchemas;
-
+ public DisplayAttributesModalPage(final PageReference pageRef, final ModalWindow window,
- final List<String> schemaNames, final List<String> dSchemaNames, final List<String> vSchemaNames) {
++ final List<String> schemaNames, final List<String> dSchemaNames) {
+
+ super();
+
+ final IModel<List<String>> fnames = new LoadableDetachableModel<List<String>>() {
+
+ private static final long serialVersionUID = 5275935387613157437L;
+
+ @Override
+ protected List<String> load() {
+ return SearchableFields.get(UserTO.class);
+ }
+ };
+
+ final IModel<List<String>> names = new LoadableDetachableModel<List<String>>() {
+
+ private static final long serialVersionUID = 5275935387613157437L;
+
+ @Override
+ protected List<String> load() {
+ return schemaNames;
+ }
+ };
+
+ final IModel<List<String>> dsnames = new LoadableDetachableModel<List<String>>() {
+
+ private static final long serialVersionUID = 5275935387613157437L;
+
+ @Override
+ protected List<String> load() {
+ return dSchemaNames;
+ }
+ };
+
- final IModel<List<String>> vsnames = new LoadableDetachableModel<List<String>>() {
-
- private static final long serialVersionUID = 5275935387613157437L;
-
- @Override
- protected List<String> load() {
- return vSchemaNames;
- }
- };
-
+ final Form form = new Form(FORM);
+ form.setModel(new CompoundPropertyModel(this));
+
+ selectedDetails = prefMan.getList(getRequest(), Constants.PREF_USERS_DETAILS_VIEW);
+
+ selectedPlainSchemas = prefMan.getList(getRequest(), Constants.PREF_USERS_ATTRIBUTES_VIEW);
+
+ selectedDerSchemas = prefMan.getList(getRequest(), Constants.PREF_USERS_DERIVED_ATTRIBUTES_VIEW);
+
- selectedVirSchemas = prefMan.getList(getRequest(), Constants.PREF_USERS_VIRTUAL_ATTRIBUTES_VIEW);
-
+ final CheckGroup dgroup = new CheckGroup("dCheckGroup", new PropertyModel(this, "selectedDetails"));
+ form.add(dgroup);
+
+ final ListView<String> details = new ListView<String>("details", fnames) {
+
+ private static final long serialVersionUID = 9101744072914090143L;
+
+ @Override
+ protected void populateItem(final ListItem<String> item) {
+ item.add(new Check("dcheck", item.getModel()));
+ item.add(new Label("dname", new ResourceModel(item.getModelObject(), item.getModelObject())));
+ }
+ };
+ dgroup.add(details);
+
+ if (names.getObject() == null || names.getObject().isEmpty()) {
+ final Fragment fragment = new Fragment("plainSchemas", "emptyFragment", form);
+ form.add(fragment);
+
+ selectedPlainSchemas.clear();
+ } else {
+ final Fragment fragment = new Fragment("plainSchemas", "sfragment", form);
+ form.add(fragment);
+
+ final CheckGroup sgroup = new CheckGroup("psCheckGroup", new PropertyModel(this, "selectedPlainSchemas"));
+ fragment.add(sgroup);
+
+ final ListView<String> schemas = new ListView<String>("plainSchemas", names) {
+
+ private static final long serialVersionUID = 9101744072914090143L;
+
+ @Override
+ protected void populateItem(final ListItem<String> item) {
+ item.add(new Check("scheck", item.getModel()));
+ item.add(new Label("sname", new ResourceModel(item.getModelObject(), item.getModelObject())));
+ }
+ };
+ sgroup.add(schemas);
+ }
+
+ if (dsnames.getObject() == null || dsnames.getObject().isEmpty()) {
+ final Fragment fragment = new Fragment("dschemas", "emptyFragment", form);
+ form.add(fragment);
+
+ selectedDerSchemas.clear();
+ } else {
+ final Fragment fragment = new Fragment("dschemas", "dsfragment", form);
+ form.add(fragment);
+
+ final CheckGroup dsgroup = new CheckGroup("dsCheckGroup", new PropertyModel(this, "selectedDerSchemas"));
+ fragment.add(dsgroup);
+
+ final ListView<String> derSchemas = new ListView<String>("derSchemas", dsnames) {
+
+ private static final long serialVersionUID = 9101744072914090143L;
+
+ @Override
+ protected void populateItem(ListItem<String> item) {
+ item.add(new Check("dscheck", item.getModel()));
+ item.add(new Label("dsname", new ResourceModel(item.getModelObject(), item.getModelObject())));
+ }
+ };
+ dsgroup.add(derSchemas);
+ }
+
- if (vsnames.getObject() == null || vsnames.getObject().isEmpty()) {
- final Fragment fragment = new Fragment("vschemas", "emptyFragment", form);
- form.add(fragment);
-
- selectedVirSchemas.clear();
- } else {
- final Fragment fragment = new Fragment("vschemas", "vsfragment", form);
- form.add(fragment);
-
- final CheckGroup vsgroup = new CheckGroup("vsCheckGroup", new PropertyModel(this, "selectedVirSchemas"));
- fragment.add(vsgroup);
-
- final ListView<String> virSchemas = new ListView<String>("virSchemas", vsnames) {
-
- private static final long serialVersionUID = 9101744072914090143L;
-
- @Override
- protected void populateItem(ListItem<String> item) {
- item.add(new Check("vscheck", item.getModel()));
- item.add(new Label("vsname", new ResourceModel(item.getModelObject(), item.getModelObject())));
- }
- };
- vsgroup.add(virSchemas);
- }
-
+ final AjaxButton submit = new IndicatingAjaxButton(SUBMIT, new ResourceModel(SUBMIT)) {
+
+ private static final long serialVersionUID = -4804368561204623354L;
+
+ @Override
+ protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
- if (selectedDetails.size() + selectedPlainSchemas.size() + selectedVirSchemas.size() + selectedDerSchemas.
- size()
++ if (selectedDetails.size() + selectedPlainSchemas.size() + selectedDerSchemas.size()
+ > MAX_SELECTIONS) {
+
+ error(getString("tooManySelections"));
+ onError(target, form);
+ } else {
- final Map<String, List<String>> prefs = new HashMap<String, List<String>>();
++ final Map<String, List<String>> prefs = new HashMap<>();
+
+ prefs.put(Constants.PREF_USERS_DETAILS_VIEW, selectedDetails);
+
+ prefs.put(Constants.PREF_USERS_ATTRIBUTES_VIEW, selectedPlainSchemas);
+
+ prefs.put(Constants.PREF_USERS_DERIVED_ATTRIBUTES_VIEW, selectedDerSchemas);
+
- prefs.put(Constants.PREF_USERS_VIRTUAL_ATTRIBUTES_VIEW, selectedVirSchemas);
-
+ prefMan.setList(getRequest(), getResponse(), prefs);
+
+ ((BasePage) pageRef.getPage()).setModalResult(true);
+
+ window.close(target);
+ }
+ }
+
+ @Override
+ protected void onError(final AjaxRequestTarget target, final Form<?> form) {
+ feedbackPanel.refresh(target);
+ }
+ };
+
+ form.add(submit);
+
+ final AjaxButton cancel = new IndicatingAjaxButton(CANCEL, new ResourceModel(CANCEL)) {
+
+ private static final long serialVersionUID = -958724007591692537L;
+
+ @Override
+ protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+ window.close(target);
+ }
+ };
+
+ cancel.setDefaultFormProcessing(false);
+ form.add(cancel);
+
+ add(form);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/97607b16/client/old_console/src/main/java/org/apache/syncope/client/console/panels/UserSearchResultPanel.java
----------------------------------------------------------------------
diff --cc client/old_console/src/main/java/org/apache/syncope/client/console/panels/UserSearchResultPanel.java
index 132bb66,0000000..16f7a22
mode 100644,000000..100644
--- a/client/old_console/src/main/java/org/apache/syncope/client/console/panels/UserSearchResultPanel.java
+++ b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/UserSearchResultPanel.java
@@@ -1,297 -1,0 +1,288 @@@
+/*
+ * 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 java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.pages.DisplayAttributesModalPage;
+import org.apache.syncope.client.console.pages.EditUserModalPage;
+import org.apache.syncope.client.console.pages.ResultStatusModalPage;
+import org.apache.syncope.client.console.pages.StatusModalPage;
+import org.apache.syncope.client.console.rest.AbstractSubjectRestClient;
+import org.apache.syncope.client.console.rest.SchemaRestClient;
+import org.apache.syncope.client.console.rest.UserRestClient;
+import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.ActionColumn;
+import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.AttrColumn;
+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.TokenColumn;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink.ActionType;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.wicket.Page;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+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.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+import org.springframework.util.ReflectionUtils;
+
+public class UserSearchResultPanel extends AbstractSearchResultPanel {
+
+ private static final long serialVersionUID = -905187144506842332L;
+
+ private final static String PAGEID = "Users";
+
+ @SpringBean
+ private SchemaRestClient schemaRestClient;
+
+ private final List<String> pSchemaNames;
+
+ private final List<String> dSchemaNames;
+
- private final List<String> vSchemaNames;
-
+ public <T extends AbstractAttributableTO> UserSearchResultPanel(final String id, final boolean filtered,
+ final String fiql, final PageReference callerRef, final AbstractSubjectRestClient restClient) {
+
+ super(id, filtered, fiql, callerRef, restClient);
+
+ this.pSchemaNames = schemaRestClient.getPlainSchemaNames(AttributableType.USER);
+ this.dSchemaNames = schemaRestClient.getDerSchemaNames(AttributableType.USER);
- this.vSchemaNames = schemaRestClient.getVirSchemaNames(AttributableType.USER);
+
+ initResultTable();
+ }
+
+ @Override
+ protected List<IColumn<AbstractAttributableTO, String>> getColumns() {
+ final List<IColumn<AbstractAttributableTO, String>> columns = new ArrayList<>();
+
+ for (String name : prefMan.getList(getRequest(), Constants.PREF_USERS_DETAILS_VIEW)) {
+ final Field field = ReflectionUtils.findField(UserTO.class, name);
+
+ if ("token".equalsIgnoreCase(name)) {
+ columns.add(new TokenColumn("token"));
+ } else if (field != null && field.getType().equals(Date.class)) {
+ columns.add(new DatePropertyColumn<AbstractAttributableTO>(new ResourceModel(name, name), name, name));
+ } else {
+ columns.add(
+ new PropertyColumn<AbstractAttributableTO, String>(new ResourceModel(name, name), name, name));
+ }
+ }
+
+ for (String name : prefMan.getList(getRequest(), Constants.PREF_USERS_ATTRIBUTES_VIEW)) {
+ if (pSchemaNames.contains(name)) {
+ columns.add(new AttrColumn(name, SchemaType.PLAIN));
+ }
+ }
+
+ for (String name : prefMan.getList(getRequest(), Constants.PREF_USERS_DERIVED_ATTRIBUTES_VIEW)) {
+ if (dSchemaNames.contains(name)) {
+ columns.add(new AttrColumn(name, SchemaType.DERIVED));
+ }
+ }
+
- for (String name : prefMan.getList(getRequest(), Constants.PREF_USERS_VIRTUAL_ATTRIBUTES_VIEW)) {
- if (vSchemaNames.contains(name)) {
- columns.add(new AttrColumn(name, SchemaType.VIRTUAL));
- }
- }
-
+ // Add defaults in case of no selection
+ if (columns.isEmpty()) {
+ for (String name : DisplayAttributesModalPage.DEFAULT_SELECTION) {
+ columns.add(
+ new PropertyColumn<AbstractAttributableTO, String>(new ResourceModel(name, name), name, name));
+ }
+
+ prefMan.setList(getRequest(), getResponse(), Constants.PREF_USERS_DETAILS_VIEW,
+ Arrays.asList(DisplayAttributesModalPage.DEFAULT_SELECTION));
+ }
+
+ columns.add(new ActionColumn<AbstractAttributableTO, String>(new ResourceModel("actions", "")) {
+
+ private static final long serialVersionUID = -3503023501954863131L;
+
+ @Override
+ public ActionLinksPanel getActions(final String componentId, final IModel<AbstractAttributableTO> model) {
+
+ final ActionLinksPanel panel = new ActionLinksPanel(componentId, model, page.getPageReference());
+
+ panel.add(new ActionLink() {
+
+ private static final long serialVersionUID = -7978723352517770644L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target) {
+ statusmodal.setPageCreator(new ModalWindow.PageCreator() {
+
+ private static final long serialVersionUID = -7834632442532690940L;
+
+ @Override
+ public Page createPage() {
+ return new StatusModalPage<UserTO>(
+ page.getPageReference(), statusmodal, (UserTO) model.getObject());
+ }
+ });
+
+ statusmodal.show(target);
+ }
+ }, ActionLink.ActionType.MANAGE_RESOURCES, PAGEID);
+
+ panel.add(new ActionLink() {
+
+ private static final long serialVersionUID = -7978723352517770644L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target) {
+ statusmodal.setPageCreator(new ModalWindow.PageCreator() {
+
+ private static final long serialVersionUID = -7834632442532690940L;
+
+ @Override
+ public Page createPage() {
+ return new StatusModalPage<UserTO>(
+ page.getPageReference(), statusmodal, (UserTO) model.getObject(), true);
+ }
+ });
+
+ statusmodal.show(target);
+ }
+ }, ActionLink.ActionType.ENABLE, PAGEID);
+
+ panel.add(new ActionLink() {
+
+ private static final long serialVersionUID = -7978723352517770644L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target) {
+ editmodal.setPageCreator(new ModalWindow.PageCreator() {
+
+ private static final long serialVersionUID = -7834632442532690940L;
+
+ @Override
+ public Page createPage() {
+ // SYNCOPE-294: re-read userTO before edit
+ UserTO userTO = ((UserRestClient) restClient).read(model.getObject().getKey());
+ return new EditUserModalPage(page.getPageReference(), editmodal, userTO);
+ }
+ });
+
+ editmodal.show(target);
+ }
+ }, ActionLink.ActionType.EDIT, PAGEID);
+
+ panel.add(new ActionLink() {
+
+ private static final long serialVersionUID = -7978723352517770644L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target) {
+ try {
+ final UserTO userTO = (UserTO) restClient.
+ delete(model.getObject().getETagValue(), model.getObject().getKey());
+
+ page.setModalResult(true);
+
+ editmodal.setPageCreator(new ModalWindow.PageCreator() {
+
+ private static final long serialVersionUID = -7834632442532690940L;
+
+ @Override
+ public Page createPage() {
+ return new ResultStatusModalPage.Builder(editmodal, userTO).build();
+ }
+ });
+
+ editmodal.show(target);
+ } catch (SyncopeClientException scce) {
+ error(getString(Constants.OPERATION_ERROR) + ": " + scce.getMessage());
+ feedbackPanel.refresh(target);
+ }
+ }
+ }, ActionLink.ActionType.DELETE, PAGEID);
+
+ return panel;
+ }
+
+ @Override
+ public ActionLinksPanel getHeader(final String componentId) {
+ final ActionLinksPanel panel = new ActionLinksPanel(componentId, new Model(), page.getPageReference());
+
+ panel.add(new ActionLink() {
+
+ private static final long serialVersionUID = -7978723352517770644L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target) {
+ displaymodal.setPageCreator(new ModalWindow.PageCreator() {
+
+ private static final long serialVersionUID = -7834632442532690940L;
+
+ @Override
+ public Page createPage() {
+ return new DisplayAttributesModalPage(page.getPageReference(), displaymodal,
- pSchemaNames, dSchemaNames, vSchemaNames);
++ pSchemaNames, dSchemaNames);
+ }
+ });
+
+ displaymodal.show(target);
+ }
+ }, ActionLink.ActionType.CHANGE_VIEW, PAGEID);
+
+ panel.add(new ActionLink() {
+
+ private static final long serialVersionUID = -7978723352517770644L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target) {
+ if (target != null) {
+ target.add(container);
+ }
+ }
+ }, ActionLink.ActionType.RELOAD, PAGEID, "list");
+
+ return panel;
+ }
+ });
+
+ return columns;
+ }
+
+ @Override
+ protected <T extends AbstractAttributableTO> Collection<ActionType> getBulkActions() {
+ final List<ActionType> bulkActions = new ArrayList<ActionType>();
+
+ bulkActions.add(ActionType.DELETE);
+ bulkActions.add(ActionType.SUSPEND);
+ bulkActions.add(ActionType.REACTIVATE);
+
+ return bulkActions;
+ }
+
+ @Override
+ protected String getPageId() {
+ return PAGEID;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/97607b16/client/old_console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
----------------------------------------------------------------------
diff --cc client/old_console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
index bca0e28,0000000..fff02bb
mode 100644,000000..100644
--- a/client/old_console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
+++ b/client/old_console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
@@@ -1,228 -1,0 +1,228 @@@
+/*
+ * 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 javax.ws.rs.core.Response;
+import org.apache.syncope.client.console.commons.status.StatusBean;
+import org.apache.syncope.client.console.commons.status.StatusUtils;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.mod.ResourceAssociationMod;
+import org.apache.syncope.common.lib.mod.StatusMod;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.common.lib.to.BulkAction;
+import org.apache.syncope.common.lib.to.BulkActionResult;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
+import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
+import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.common.lib.wrap.ResourceName;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
+import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.apache.syncope.common.rest.api.service.UserService;
+import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
+import org.springframework.stereotype.Component;
+
+/**
+ * Console client for invoking rest users services.
+ */
+@Component
+public class UserRestClient extends AbstractSubjectRestClient {
+
+ private static final long serialVersionUID = -1575748964398293968L;
+
+ @Override
+ public int count() {
+ return getService(UserService.class).list(1, 1).getTotalCount();
+ }
+
+ @Override
+ public List<UserTO> list(final int page, final int size, final SortParam<String> sort) {
- return getService(UserService.class).list(page, size, toOrderBy(sort)).getResult();
++ return getService(UserService.class).list(page, size, toOrderBy(sort), false).getResult();
+ }
+
+ public UserTO create(final UserTO userTO, final boolean storePassword) {
+ Response response = getService(UserService.class).create(userTO, storePassword);
+ return response.readEntity(UserTO.class);
+ }
+
+ public UserTO update(final String etag, final UserMod userMod) {
+ UserTO result;
+ synchronized (this) {
+ UserService service = getService(etag, UserService.class);
+ result = service.update(userMod.getKey(), userMod).readEntity(UserTO.class);
+ resetClient(UserService.class);
+ }
+ return result;
+ }
+
+ @Override
+ public UserTO delete(final String etag, final Long id) {
+ UserTO result;
+ synchronized (this) {
+ UserService service = getService(etag, UserService.class);
+ result = service.delete(id).readEntity(UserTO.class);
+ resetClient(UserService.class);
+ }
+ return result;
+ }
+
+ public UserTO read(final Long id) {
+ UserTO userTO = null;
+ try {
+ userTO = getService(UserService.class).read(id);
+ } catch (SyncopeClientException e) {
+ LOG.error("While reading a user", e);
+ }
+ return userTO;
+ }
+
+ @Override
+ public int searchCount(final String fiql) {
+ return getService(UserService.class).search(fiql, 1, 1).getTotalCount();
+ }
+
+ @Override
+ public List<UserTO> search(final String fiql, final int page, final int size, final SortParam<String> sort) {
- return getService(UserService.class).search(fiql, page, size, toOrderBy(sort)).getResult();
++ return getService(UserService.class).search(fiql, page, size, toOrderBy(sort), false).getResult();
+ }
+
+ @Override
+ public ConnObjectTO getConnectorObject(final String resourceName, final Long id) {
+ return getService(ResourceService.class).getConnectorObject(resourceName, SubjectType.USER, id);
+ }
+
+ public void suspend(final String etag, final long userId, final List<StatusBean> statuses) {
+ StatusMod statusMod = StatusUtils.buildStatusMod(statuses, false);
+ statusMod.setType(StatusMod.ModType.SUSPEND);
+ synchronized (this) {
+ UserService service = getService(etag, UserService.class);
+ service.status(userId, statusMod);
+ resetClient(UserService.class);
+ }
+ }
+
+ public void reactivate(final String etag, final long userId, final List<StatusBean> statuses) {
+ StatusMod statusMod = StatusUtils.buildStatusMod(statuses, true);
+ statusMod.setType(StatusMod.ModType.REACTIVATE);
+ synchronized (this) {
+ UserService service = getService(etag, UserService.class);
+ service.status(userId, statusMod);
+ resetClient(UserService.class);
+ }
+ }
+
+ @Override
+ public BulkActionResult bulkAction(final BulkAction action) {
+ return getService(UserService.class).bulk(action);
+ }
+
+ public void unlink(final String etag, final long userId, final List<StatusBean> statuses) {
+ synchronized (this) {
+ UserService service = getService(etag, UserService.class);
+ service.bulkDeassociation(userId, ResourceDeassociationActionType.UNLINK,
+ CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
+ ResourceName.class));
+ resetClient(UserService.class);
+ }
+ }
+
+ public void link(final String etag, final long userId, final List<StatusBean> statuses) {
+ synchronized (this) {
+ UserService service = getService(etag, UserService.class);
+
+ final ResourceAssociationMod associationMod = new ResourceAssociationMod();
+ associationMod.getTargetResources().addAll(
+ CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
+ ResourceName.class));
+ service.bulkAssociation(userId, ResourceAssociationActionType.LINK, associationMod);
+
+ resetClient(UserService.class);
+ }
+ }
+
+ public BulkActionResult deprovision(final String etag, final long userId, final List<StatusBean> statuses) {
+ BulkActionResult result;
+ synchronized (this) {
+ UserService service = getService(etag, UserService.class);
+ result = service.bulkDeassociation(userId, ResourceDeassociationActionType.DEPROVISION,
+ CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
+ ResourceName.class)).
+ readEntity(BulkActionResult.class);
+ resetClient(UserService.class);
+ }
+ return result;
+ }
+
+ public BulkActionResult provision(final String etag, final long userId,
+ final List<StatusBean> statuses, final boolean changepwd, final String password) {
+
+ BulkActionResult result;
+ synchronized (this) {
+ UserService service = getService(etag, UserService.class);
+
+ final ResourceAssociationMod associationMod = new ResourceAssociationMod();
+ associationMod.getTargetResources().addAll(
+ CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
+ ResourceName.class));
+ associationMod.setChangePwd(changepwd);
+ associationMod.setPassword(password);
+
+ result = service.bulkAssociation(userId, ResourceAssociationActionType.PROVISION, associationMod).
+ readEntity(BulkActionResult.class);
+ resetClient(UserService.class);
+ }
+ return result;
+ }
+
+ public BulkActionResult unassign(final String etag, final long userId, final List<StatusBean> statuses) {
+ BulkActionResult result;
+ synchronized (this) {
+ UserService service = getService(etag, UserService.class);
+ result = service.bulkDeassociation(userId, ResourceDeassociationActionType.UNASSIGN,
+ CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
+ ResourceName.class)).
+ readEntity(BulkActionResult.class);
+ resetClient(UserService.class);
+ }
+ return result;
+ }
+
+ public BulkActionResult assign(final String etag, final long userId,
+ final List<StatusBean> statuses, final boolean changepwd, final String password) {
+
+ BulkActionResult result;
+ synchronized (this) {
+ UserService service = getService(etag, UserService.class);
+
+ final ResourceAssociationMod associationMod = new ResourceAssociationMod();
+ associationMod.getTargetResources().addAll(
+ CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
+ ResourceName.class));
+ associationMod.setChangePwd(changepwd);
+ associationMod.setPassword(password);
+
+ result = service.bulkAssociation(userId, ResourceAssociationActionType.ASSIGN, associationMod).
+ readEntity(BulkActionResult.class);
+ resetClient(UserService.class);
+ }
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/97607b16/client/old_console/src/main/resources/org/apache/syncope/client/console/pages/DisplayAttributesModalPage.html
----------------------------------------------------------------------
diff --cc client/old_console/src/main/resources/org/apache/syncope/client/console/pages/DisplayAttributesModalPage.html
index 998483d,0000000..4e4064c
mode 100644,000000..100644
--- a/client/old_console/src/main/resources/org/apache/syncope/client/console/pages/DisplayAttributesModalPage.html
+++ b/client/old_console/src/main/resources/org/apache/syncope/client/console/pages/DisplayAttributesModalPage.html
@@@ -1,132 -1,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.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+ <wicket:head>
+ <style>
+ div.group{
+ width:450px;
+ }
+
+ div.group div{
+ width:150;
+ height: 25px;
+ float:left;
+ }
+
+ div.group div input {
+ width: 30px;
+ }
+
+ div#attributes-view {
+ display: block;
+ clear: both;
+ float: none;
+ overflow: auto;
+ margin-top: 0px;
+ margin-bottom: 20px;
+ margin-left: 10px;
+ margin-right: 10px;
+ }
+
+ .submit{
+ display: block;
+ clear: both;
+ float: none;
+ margin-left: 10px;
+ }
+
+ span.grouplabel{
+ display:block;
+ clear: both;
+ margin-left: 10px;
+ margin-bottom: 10px;
+ font-weight: bold;
+ }
+ </style>
+ </wicket:head>
+ <wicket:extend>
+ <form wicket:id="form">
+ <div id="attributes-view">
+ <p class="ui-widget ui-corner-all ui-widget-header">
+ <wicket:message key="title"/>
+ </p>
+
+ <span class="grouplabel"><wicket:message key="plainSchemas"/></span>
+ <span wicket:id="dCheckGroup">
+ <div class="group">
+ <div wicket:id="details">
+ <input type="checkbox" wicket:id="dcheck"/>
+ <span wicket:id="dname">[schema name]</span>
+ </div>
+ </div>
+ </span>
+
+ <span wicket:id="plainSchemas">[schemas]</span>
+
+ <span wicket:id="dschemas">[derived schemas]</span>
+
- <span wicket:id="vschemas">[virtual schemas]</span>
-
+ </div>
+
+ <wicket:fragment wicket:id="sfragment">
+ <span wicket:id="psCheckGroup">
+ <div class="group">
+ <div wicket:id="plainSchemas">
+ <input type="checkbox" wicket:id="scheck"/>
+ <span wicket:id="sname">[schema name]</span>
+ </div>
+ </div>
+ </span>
+ </wicket:fragment>
+
+ <wicket:fragment wicket:id="dsfragment">
+ <span class="grouplabel"><wicket:message key="derSchemas"/></span>
+ <span wicket:id="dsCheckGroup">
+ <div class="group">
+ <div wicket:id="derSchemas">
+ <input type="checkbox" wicket:id="dscheck"/>
+ <span wicket:id="dsname">[schema name]</span>
+ </div>
+ </div>
+ </span>
+ </wicket:fragment>
+
+ <wicket:fragment wicket:id="vsfragment">
+ <span class="grouplabel"><wicket:message key="virSchemas"/></span>
+ <span wicket:id="vsCheckGroup">
+ <div class="group">
+ <div wicket:id="virSchemas">
+ <input type="checkbox" wicket:id="vscheck"/>
+ <span wicket:id="vsname">[schema name]</span>
+ </div>
+ </div>
+ </span>
+ </wicket:fragment>
+
+ <wicket:fragment wicket:id="emptyFragment">
+ </wicket:fragment>
+
+ <div class="submit">
+ <input type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" wicket:id="submit"/>
+ <input type="button" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" wicket:id="cancel"/>
+ </div>
+ </form>
+ </wicket:extend>
+</html>
http://git-wip-us.apache.org/repos/asf/syncope/blob/97607b16/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ListQuery.java
----------------------------------------------------------------------
diff --cc common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ListQuery.java
index 1a85fe4,0000000..96fe514
mode 100644,000000..100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ListQuery.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/ListQuery.java
@@@ -1,86 -1,0 +1,98 @@@
+/*
+ * 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 java.io.Serializable;
+import javax.validation.constraints.Min;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.QueryParam;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import org.apache.syncope.common.rest.api.service.JAXRSService;
+
+public class ListQuery implements Serializable {
+
+ private static final long serialVersionUID = -371488230250055359L;
+
+ private Integer page;
+
+ private Integer size;
+
+ private String orderBy;
+
++ private Boolean details;
++
+ public Integer getPage() {
+ return page;
+ }
+
+ @Min(1)
+ @QueryParam(JAXRSService.PARAM_PAGE)
+ @DefaultValue("1")
+ public void setPage(final Integer page) {
+ this.page = page;
+ }
+
+ public Integer getSize() {
+ return size;
+ }
+
+ @Min(1)
+ @QueryParam(JAXRSService.PARAM_SIZE)
+ @DefaultValue("25")
+ public void setSize(final Integer size) {
+ this.size = size;
+ }
+
+ @QueryParam(JAXRSService.PARAM_ORDERBY)
+ public String getOrderBy() {
+ return orderBy;
+ }
+
+ public void setOrderBy(final String orderBy) {
+ this.orderBy = orderBy;
+ }
+
++ @QueryParam(JAXRSService.PARAM_DETAILS)
++ @DefaultValue("true")
++ public boolean isDetails() {
++ return details == null ? true : details;
++ }
++
++ public void setDetails(final boolean details) {
++ this.details = details;
++ }
++
+ @Override
+ public boolean equals(final Object obj) {
+ return EqualsBuilder.reflectionEquals(this, obj);
+ }
+
+ @Override
+ public int hashCode() {
+ return HashCodeBuilder.reflectionHashCode(this);
+ }
+
+ @Override
+ public String toString() {
+ return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/97607b16/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/JAXRSService.java
----------------------------------------------------------------------
diff --cc common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/JAXRSService.java
index bfd166a,0000000..c6c73d5
mode 100644,000000..100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/JAXRSService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/JAXRSService.java
@@@ -1,31 -1,0 +1,33 @@@
+/*
+ * 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;
+
+public interface JAXRSService {
+
+ String PARAM_FIQL = "fiql";
+
+ String PARAM_PAGE = "page";
+
+ String PARAM_SIZE = "size";
+
+ String PARAM_ORDERBY = "orderby";
+
++ String PARAM_DETAILS = "details";
++
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/97607b16/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
----------------------------------------------------------------------
diff --cc core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
index d24b08e,0000000..6f66113
mode 100644,000000..100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
@@@ -1,86 -1,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;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.syncope.common.lib.mod.AnyMod;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.core.misc.RealmUtils;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+
+public abstract class AbstractAnyLogic<TO extends AnyTO, MOD extends AnyMod>
+ extends AbstractResourceAssociator<TO> {
+
+ private static class StartsWithPredicate implements Predicate<String> {
+
+ private final Collection<String> targets;
+
+ public StartsWithPredicate(final Collection<String> targets) {
+ this.targets = targets;
+ }
+
+ @Override
+ public boolean evaluate(final String realm) {
+ return CollectionUtils.exists(targets, new Predicate<String>() {
+
+ @Override
+ public boolean evaluate(final String target) {
+ return realm.startsWith(target);
+ }
+ });
+ }
+
+ }
+
+ protected Set<String> getEffectiveRealms(
+ final Set<String> allowedRealms, final Collection<String> requestedRealms) {
+
+ final Set<String> allowed = RealmUtils.normalize(allowedRealms);
+ final Set<String> requested = RealmUtils.normalize(requestedRealms);
+
+ Set<String> effective = new HashSet<>();
+ CollectionUtils.select(requested, new StartsWithPredicate(allowed), effective);
+ CollectionUtils.select(allowed, new StartsWithPredicate(requested), effective);
+
+ return effective;
+ }
+
+ public abstract TO read(Long key);
+
+ public abstract int count(List<String> realms);
+
+ public abstract TO create(TO anyTO);
+
+ public abstract TO update(MOD anyMod);
+
+ public abstract TO delete(Long key);
+
- public abstract List<TO> list(int page, int size, List<OrderByClause> orderBy, List<String> realms);
++ public abstract List<TO> list(
++ int page, int size, List<OrderByClause> orderBy,
++ List<String> realms,
++ boolean details);
+
+ public abstract List<TO> search(
- SearchCond searchCondition, int page, int size, List<OrderByClause> orderBy, List<String> realms);
++ SearchCond searchCondition,
++ int page, int size, List<OrderByClause> orderBy,
++ List<String> realms,
++ boolean details);
+
+ public abstract int searchCount(SearchCond searchCondition, List<String> realms);
+}