[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ò <[email protected]> Authored: Tue Jul 7 09:37:35 2015 +0200 Committer: Francesco Chicchiriccò <[email protected]> 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); +}
