Author: ilgrosso Date: Fri Dec 21 10:31:10 2012 New Revision: 1424852 URL: http://svn.apache.org/viewvc?rev=1424852&view=rev Log: [SYNCOPE-44] Enhancing search: AttributableCond now with boolean and relationship fields support, EntitlementCond added
Added: syncope/trunk/client/src/main/java/org/apache/syncope/client/search/EntitlementCond.java (with props) syncope/trunk/client/src/main/java/org/apache/syncope/client/search/SearchCond.java (with props) Removed: syncope/trunk/core/src/main/java/org/apache/syncope/core/validation/ Modified: syncope/trunk/client/src/main/java/org/apache/syncope/client/search/AttributableCond.java syncope/trunk/client/src/main/java/org/apache/syncope/client/search/AttributeCond.java syncope/trunk/client/src/main/java/org/apache/syncope/client/search/MembershipCond.java syncope/trunk/client/src/main/java/org/apache/syncope/client/search/NodeCond.java syncope/trunk/client/src/main/java/org/apache/syncope/client/search/ResourceCond.java syncope/trunk/client/src/test/java/org/apache/syncope/client/test/JSONTest.java syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Roles.java syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/UserOwnerSelectModalPage.java syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Users.java syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractBaseBean.java syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/AttributableSearchDAOImpl.java syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/NotificationValidator.java syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/RoleController.java syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/AttributableSearchTest.java syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/NotificationTest.java syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/relationships/AttributableSearchTest.java syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/SearchTestITCase.java Modified: syncope/trunk/client/src/main/java/org/apache/syncope/client/search/AttributableCond.java URL: http://svn.apache.org/viewvc/syncope/trunk/client/src/main/java/org/apache/syncope/client/search/AttributableCond.java?rev=1424852&r1=1424851&r2=1424852&view=diff ============================================================================== --- syncope/trunk/client/src/main/java/org/apache/syncope/client/search/AttributableCond.java (original) +++ syncope/trunk/client/src/main/java/org/apache/syncope/client/search/AttributableCond.java Fri Dec 21 10:31:10 2012 @@ -19,16 +19,16 @@ package org.apache.syncope.client.search; /** - * Search condition to be applied when comparing bean attribute values. + * Search condition to be applied when comparing bean field values. */ -public class AttributableCond extends AttributeCond { +public class AttributableCond extends AttributeCond implements SearchCond { private static final long serialVersionUID = -1880319220462653955L; public AttributableCond() { } - public AttributableCond(Type conditionType) { + public AttributableCond(final Type conditionType) { super(conditionType); } } Modified: syncope/trunk/client/src/main/java/org/apache/syncope/client/search/AttributeCond.java URL: http://svn.apache.org/viewvc/syncope/trunk/client/src/main/java/org/apache/syncope/client/search/AttributeCond.java?rev=1424852&r1=1424851&r2=1424852&view=diff ============================================================================== --- syncope/trunk/client/src/main/java/org/apache/syncope/client/search/AttributeCond.java (original) +++ syncope/trunk/client/src/main/java/org/apache/syncope/client/search/AttributeCond.java Fri Dec 21 10:31:10 2012 @@ -23,7 +23,7 @@ import org.apache.syncope.client.Abstrac /** * Search condition to be applied when comparing attribute values. */ -public class AttributeCond extends AbstractBaseBean { +public class AttributeCond extends AbstractBaseBean implements SearchCond { private static final long serialVersionUID = 3275277728404021417L; @@ -79,7 +79,8 @@ public class AttributeCond extends Abstr this.type = conditionType; } - public final boolean checkValidity() { + @Override + public final boolean isValid() { return type != null && schema != null && (type == Type.ISNULL || type == Type.ISNOTNULL || expression != null); } } Added: syncope/trunk/client/src/main/java/org/apache/syncope/client/search/EntitlementCond.java URL: http://svn.apache.org/viewvc/syncope/trunk/client/src/main/java/org/apache/syncope/client/search/EntitlementCond.java?rev=1424852&view=auto ============================================================================== --- syncope/trunk/client/src/main/java/org/apache/syncope/client/search/EntitlementCond.java (added) +++ syncope/trunk/client/src/main/java/org/apache/syncope/client/search/EntitlementCond.java Fri Dec 21 10:31:10 2012 @@ -0,0 +1,41 @@ +/* + * 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.search; + +import org.apache.syncope.client.AbstractBaseBean; + +public class EntitlementCond extends AbstractBaseBean implements SearchCond { + + private static final long serialVersionUID = -4077781080368377428L; + + private String expression; + + public String getExpression() { + return expression; + } + + public void setExpression(final String expression) { + this.expression = expression; + } + + @Override + public boolean isValid() { + return expression != null; + } +} Propchange: syncope/trunk/client/src/main/java/org/apache/syncope/client/search/EntitlementCond.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: syncope/trunk/client/src/main/java/org/apache/syncope/client/search/EntitlementCond.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Propchange: syncope/trunk/client/src/main/java/org/apache/syncope/client/search/EntitlementCond.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: syncope/trunk/client/src/main/java/org/apache/syncope/client/search/MembershipCond.java URL: http://svn.apache.org/viewvc/syncope/trunk/client/src/main/java/org/apache/syncope/client/search/MembershipCond.java?rev=1424852&r1=1424851&r2=1424852&view=diff ============================================================================== --- syncope/trunk/client/src/main/java/org/apache/syncope/client/search/MembershipCond.java (original) +++ syncope/trunk/client/src/main/java/org/apache/syncope/client/search/MembershipCond.java Fri Dec 21 10:31:10 2012 @@ -23,7 +23,7 @@ import org.apache.syncope.client.Abstrac /** * Search condition to be applied when searching for memberships. */ -public class MembershipCond extends AbstractBaseBean { +public class MembershipCond extends AbstractBaseBean implements SearchCond { private static final long serialVersionUID = -728155256293925989L; @@ -51,7 +51,8 @@ public class MembershipCond extends Abst this.roleName = roleName; } - public final boolean checkValidity() { + @Override + public final boolean isValid() { return !(roleId == null && roleName == null); } } Modified: syncope/trunk/client/src/main/java/org/apache/syncope/client/search/NodeCond.java URL: http://svn.apache.org/viewvc/syncope/trunk/client/src/main/java/org/apache/syncope/client/search/NodeCond.java?rev=1424852&r1=1424851&r2=1424852&view=diff ============================================================================== --- syncope/trunk/client/src/main/java/org/apache/syncope/client/search/NodeCond.java (original) +++ syncope/trunk/client/src/main/java/org/apache/syncope/client/search/NodeCond.java Fri Dec 21 10:31:10 2012 @@ -19,6 +19,7 @@ package org.apache.syncope.client.search; import org.apache.syncope.client.AbstractBaseBean; +import org.codehaus.jackson.annotate.JsonIgnore; public class NodeCond extends AbstractBaseBean { @@ -28,6 +29,7 @@ public class NodeCond extends AbstractBa NOT_LEAF, AND, OR + } private Type type; @@ -40,6 +42,8 @@ public class NodeCond extends AbstractBa private ResourceCond resourceCond; + private EntitlementCond entitlementCond; + private NodeCond leftNodeCond; private NodeCond rightNodeCond; @@ -80,6 +84,15 @@ public class NodeCond extends AbstractBa return nodeCond; } + public static NodeCond getLeafCond(final EntitlementCond entitlementCond) { + NodeCond nodeCond = new NodeCond(); + + nodeCond.type = Type.LEAF; + nodeCond.entitlementCond = entitlementCond; + + return nodeCond; + } + public static NodeCond getNotLeafCond(final AttributableCond syncopeUserCond) { NodeCond nodeCond = getLeafCond(syncopeUserCond); nodeCond.type = Type.NOT_LEAF; @@ -104,8 +117,13 @@ public class NodeCond extends AbstractBa return nodeCond; } - public static NodeCond getAndCond(final NodeCond leftCond, final NodeCond rightCond) { + public static NodeCond getNotLeafCond(final EntitlementCond entitlementCond) { + NodeCond nodeCond = getLeafCond(entitlementCond); + nodeCond.type = Type.NOT_LEAF; + return nodeCond; + } + public static NodeCond getAndCond(final NodeCond leftCond, final NodeCond rightCond) { NodeCond nodeCond = new NodeCond(); nodeCond.type = Type.AND; @@ -116,7 +134,6 @@ public class NodeCond extends AbstractBa } public static NodeCond getOrCond(final NodeCond leftCond, final NodeCond rightCond) { - NodeCond nodeCond = new NodeCond(); nodeCond.type = Type.OR; @@ -126,85 +143,100 @@ public class NodeCond extends AbstractBa return nodeCond; } + public AttributableCond getAttributableCond() { + return attributableCond; + } + + public void setAttributableCond(final AttributableCond attributableCond) { + this.attributableCond = attributableCond; + } + public AttributeCond getAttributeCond() { return attributeCond; } - public final void setAttributeCond(final AttributeCond attributeCond) { + public void setAttributeCond(final AttributeCond attributeCond) { this.attributeCond = attributeCond; } - public final MembershipCond getMembershipCond() { + public MembershipCond getMembershipCond() { return membershipCond; } - public final ResourceCond getResourceCond() { - return resourceCond; + public void setMembershipCond(final MembershipCond membershipCond) { + this.membershipCond = membershipCond; } - public final void setMembershipCond(final MembershipCond membershipCond) { - this.membershipCond = membershipCond; + public ResourceCond getResourceCond() { + return resourceCond; } public void setResourceCond(final ResourceCond resourceCond) { this.resourceCond = resourceCond; } - public AttributableCond getAttributableCond() { - return attributableCond; + public EntitlementCond getEntitlementCond() { + return entitlementCond; } - public void setAttributableCond(final AttributableCond attributableCond) { - this.attributableCond = attributableCond; + public void setEntitlementCond(final EntitlementCond entitlementCond) { + this.entitlementCond = entitlementCond; } - public final NodeCond getLeftNodeCond() { + public NodeCond getLeftNodeCond() { return leftNodeCond; } - public final void setLeftNodeCond(final NodeCond leftNodeCond) { + public void setLeftNodeCond(final NodeCond leftNodeCond) { this.leftNodeCond = leftNodeCond; } - public final NodeCond getRightNodeCond() { + public NodeCond getRightNodeCond() { return rightNodeCond; } - public final void setRightNodeCond(final NodeCond rightNodeCond) { + public void setRightNodeCond(final NodeCond rightNodeCond) { this.rightNodeCond = rightNodeCond; } - public final Type getType() { + public Type getType() { return type; } - public final void setType(final Type type) { + public void setType(final Type type) { this.type = type; } - public final boolean checkValidity() { + @JsonIgnore + public boolean isValid() { + boolean isValid = false; + if (type == null) { - return false; + return isValid; } switch (type) { case LEAF: case NOT_LEAF: - return (attributableCond != null && attributeCond == null && membershipCond == null - && resourceCond == null && attributableCond.checkValidity()) - || (attributableCond == null && attributeCond != null && membershipCond == null - && resourceCond == null && attributeCond.checkValidity()) - || (attributableCond == null && attributeCond == null && membershipCond != null - && resourceCond == null && membershipCond.checkValidity()) - || (attributableCond == null && attributeCond == null && membershipCond == null - && resourceCond != null && resourceCond.checkValidity()); + isValid = (attributableCond != null || attributeCond != null || membershipCond != null + || resourceCond != null || entitlementCond != null) + && (attributableCond == null || attributableCond.isValid()) + && (attributeCond == null || attributeCond.isValid()) + && (membershipCond == null || membershipCond.isValid()) + && (resourceCond == null || resourceCond.isValid()) + && (entitlementCond == null || entitlementCond.isValid()); + break; + case AND: case OR: - return (leftNodeCond == null || rightNodeCond == null) + isValid = (leftNodeCond == null || rightNodeCond == null) ? false - : leftNodeCond.checkValidity() && rightNodeCond.checkValidity(); + : leftNodeCond.isValid() && rightNodeCond.isValid(); + break; + default: - return false; } + + return isValid; } } Modified: syncope/trunk/client/src/main/java/org/apache/syncope/client/search/ResourceCond.java URL: http://svn.apache.org/viewvc/syncope/trunk/client/src/main/java/org/apache/syncope/client/search/ResourceCond.java?rev=1424852&r1=1424851&r2=1424852&view=diff ============================================================================== --- syncope/trunk/client/src/main/java/org/apache/syncope/client/search/ResourceCond.java (original) +++ syncope/trunk/client/src/main/java/org/apache/syncope/client/search/ResourceCond.java Fri Dec 21 10:31:10 2012 @@ -23,7 +23,7 @@ import org.apache.syncope.client.Abstrac /** * Search condition to be applied when searching for associated resources. */ -public class ResourceCond extends AbstractBaseBean { +public class ResourceCond extends AbstractBaseBean implements SearchCond { private String resourceName; @@ -35,7 +35,8 @@ public class ResourceCond extends Abstra this.resourceName = resourceName; } - public final boolean checkValidity() { + @Override + public final boolean isValid() { return resourceName != null; } } Added: syncope/trunk/client/src/main/java/org/apache/syncope/client/search/SearchCond.java URL: http://svn.apache.org/viewvc/syncope/trunk/client/src/main/java/org/apache/syncope/client/search/SearchCond.java?rev=1424852&view=auto ============================================================================== --- syncope/trunk/client/src/main/java/org/apache/syncope/client/search/SearchCond.java (added) +++ syncope/trunk/client/src/main/java/org/apache/syncope/client/search/SearchCond.java Fri Dec 21 10:31:10 2012 @@ -0,0 +1,27 @@ +/* + * 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.search; + +import org.codehaus.jackson.annotate.JsonIgnore; + +public interface SearchCond { + + @JsonIgnore + boolean isValid(); +} Propchange: syncope/trunk/client/src/main/java/org/apache/syncope/client/search/SearchCond.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: syncope/trunk/client/src/main/java/org/apache/syncope/client/search/SearchCond.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Propchange: syncope/trunk/client/src/main/java/org/apache/syncope/client/search/SearchCond.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: syncope/trunk/client/src/test/java/org/apache/syncope/client/test/JSONTest.java URL: http://svn.apache.org/viewvc/syncope/trunk/client/src/test/java/org/apache/syncope/client/test/JSONTest.java?rev=1424852&r1=1424851&r2=1424852&view=diff ============================================================================== --- syncope/trunk/client/src/test/java/org/apache/syncope/client/test/JSONTest.java (original) +++ syncope/trunk/client/src/test/java/org/apache/syncope/client/test/JSONTest.java Fri Dec 21 10:31:10 2012 @@ -52,7 +52,7 @@ public class JSONTest { final NodeCond searchCondition = NodeCond.getAndCond(NodeCond.getLeafCond(usernameCond), NodeCond.getLeafCond( membershipCond)); - assertTrue(searchCondition.checkValidity()); + assertTrue(searchCondition.isValid()); ObjectMapper mapper = new ObjectMapper(); Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Roles.java URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Roles.java?rev=1424852&r1=1424851&r2=1424852&view=diff ============================================================================== --- syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Roles.java (original) +++ syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Roles.java Fri Dec 21 10:31:10 2012 @@ -137,7 +137,7 @@ public class Roles extends BasePage { private void doSearch(final AjaxRequestTarget target, final NodeCond searchCond, final AbstractSearchResultPanel resultsetPanel) { - if (searchCond == null || !searchCond.checkValidity()) { + if (searchCond == null || !searchCond.isValid()) { error(getString("search_error")); return; } Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/UserOwnerSelectModalPage.java URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/UserOwnerSelectModalPage.java?rev=1424852&r1=1424851&r2=1424852&view=diff ============================================================================== --- syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/UserOwnerSelectModalPage.java (original) +++ syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/UserOwnerSelectModalPage.java Fri Dec 21 10:31:10 2012 @@ -78,7 +78,7 @@ public class UserOwnerSelectModalPage ex private void doSearch(final AjaxRequestTarget target, final NodeCond searchCond, final AbstractSearchResultPanel resultsetPanel) { - if (searchCond == null || !searchCond.checkValidity()) { + if (searchCond == null || !searchCond.isValid()) { error(getString("search_error")); return; } Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Users.java URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Users.java?rev=1424852&r1=1424851&r2=1424852&view=diff ============================================================================== --- syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Users.java (original) +++ syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Users.java Fri Dec 21 10:31:10 2012 @@ -128,7 +128,7 @@ public class Users extends BasePage { private void doSearch(final AjaxRequestTarget target, final NodeCond searchCond, final AbstractSearchResultPanel resultsetPanel) { - if (searchCond == null || !searchCond.checkValidity()) { + if (searchCond == null || !searchCond.isValid()) { error(getString("search_error")); return; } Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractBaseBean.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractBaseBean.java?rev=1424852&r1=1424851&r2=1424852&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractBaseBean.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractBaseBean.java Fri Dec 21 10:31:10 2012 @@ -118,7 +118,7 @@ public abstract class AbstractBaseBean i method = BeanUtils.findMethod(getClass(), "getName"); } - StringBuffer result = new StringBuffer().append(getClass().getSimpleName()).append("["); + StringBuffer result = new StringBuffer().append(getClass().getSimpleName()).append('['); if (method != null) { try { result.append(method.invoke(this)); @@ -128,7 +128,7 @@ public abstract class AbstractBaseBean i } } } - result.append("]"); + result.append(']'); return result.toString(); } Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/AttributableSearchDAOImpl.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/AttributableSearchDAOImpl.java?rev=1424852&r1=1424851&r2=1424852&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/AttributableSearchDAOImpl.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/AttributableSearchDAOImpl.java Fri Dec 21 10:31:10 2012 @@ -18,6 +18,7 @@ */ package org.apache.syncope.core.persistence.dao.impl; +import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collections; @@ -25,17 +26,23 @@ import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; +import javax.persistence.Entity; import javax.persistence.Query; import javax.persistence.TemporalType; import javax.validation.ValidationException; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; import org.apache.syncope.client.search.AttributableCond; import org.apache.syncope.client.search.AttributeCond; +import org.apache.syncope.client.search.EntitlementCond; import org.apache.syncope.client.search.MembershipCond; import org.apache.syncope.client.search.NodeCond; import org.apache.syncope.client.search.ResourceCond; import org.apache.syncope.core.persistence.beans.AbstractAttrValue; import org.apache.syncope.core.persistence.beans.AbstractAttributable; import org.apache.syncope.core.persistence.beans.AbstractSchema; +import org.apache.syncope.core.persistence.beans.Entitlement; +import org.apache.syncope.core.persistence.beans.role.SyncopeRole; import org.apache.syncope.core.persistence.dao.AttributableSearchDAO; import org.apache.syncope.core.persistence.dao.RoleDAO; import org.apache.syncope.core.persistence.dao.SchemaDAO; @@ -43,6 +50,7 @@ import org.apache.syncope.core.persisten import org.apache.syncope.core.util.AttributableUtil; import org.apache.syncope.types.AttributableType; import org.apache.syncope.types.SchemaType; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; @@ -131,12 +139,12 @@ public class AttributableSearchDAOImpl e public <T extends AbstractAttributable> List<T> search(final Set<Long> adminRoles, final NodeCond searchCondition, final int page, final int itemsPerPage, final AttributableUtil attrUtil) { - List<T> result = Collections.EMPTY_LIST; + List<T> result = Collections.<T>emptyList(); if (adminRoles != null && (!adminRoles.isEmpty() || roleDAO.findAll().isEmpty())) { LOG.debug("Search condition:\n{}", searchCondition); - if (searchCondition.checkValidity()) { + if (searchCondition.isValid()) { try { result = doSearch(adminRoles, searchCondition, page, itemsPerPage, attrUtil); } catch (Exception e) { @@ -170,9 +178,7 @@ public class AttributableSearchDAOImpl e fillWithParameters(query, parameters); // 5. executes query - List<T> result = query.getResultList(); - - return !result.isEmpty(); + return !query.getResultList().isEmpty(); } private int setParameter(final List<Object> parameters, final Object parameter) { @@ -281,6 +287,10 @@ public class AttributableSearchDAOImpl e query.append(getQuery(nodeCond.getResourceCond(), nodeCond.getType() == NodeCond.Type.NOT_LEAF, parameters, attrUtil)); } + if (nodeCond.getEntitlementCond() != null) { + query.append(getQuery(nodeCond.getEntitlementCond(), nodeCond.getType() == NodeCond.Type.NOT_LEAF, + parameters, attrUtil)); + } if (nodeCond.getAttributeCond() != null) { query.append(getQuery(nodeCond.getAttributeCond(), nodeCond.getType() == NodeCond.Type.NOT_LEAF, parameters, attrUtil)); @@ -333,7 +343,7 @@ public class AttributableSearchDAOImpl e query.append("role_name=?").append(setParameter(parameters, cond.getRoleName())); } - query.append(")"); + query.append(')'); return query.toString(); } @@ -355,7 +365,21 @@ public class AttributableSearchDAOImpl e query.append("resource_name=?").append(setParameter(parameters, cond.getResourceName())); - query.append(")"); + query.append(')'); + + return query.toString(); + } + + private String getQuery(final EntitlementCond cond, final boolean not, final List<Object> parameters, + final AttributableUtil attrUtil) { + + final StringBuilder query = new StringBuilder("SELECT DISTINCT role_id AS subject_id FROM "). + append(SyncopeRole.class.getSimpleName()).append('_').append(Entitlement.class.getSimpleName()). + append(" WHERE entitlement_name "); + if (not) { + query.append(" NOT "); + } + query.append(" LIKE '%").append(cond.getExpression()).append("%'"); return query.toString(); } @@ -383,14 +407,11 @@ public class AttributableSearchDAOImpl e case LIKE: if (schema.getType() == SchemaType.String || schema.getType() == SchemaType.Enum) { - query.append(column); if (not) { query.append(" NOT "); } - query.append(" LIKE '").append(cond.getExpression()).append("'"); - } else { if (!(cond instanceof AttributableCond)) { query.append("' AND"); @@ -487,7 +508,7 @@ public class AttributableSearchDAOImpl e } private String getQuery(final AttributeCond cond, final boolean not, final List<Object> parameters, - AttributableUtil attrUtil) { + final AttributableUtil attrUtil) { AbstractSchema schema = schemaDAO.find(cond.getSchema(), attrUtil.schemaClass()); if (schema == null) { @@ -543,6 +564,42 @@ public class AttributableSearchDAOImpl e } } + // Deal with Attirbutable Integer fields logically mapping to boolean values + // (SyncopeRole.inheritAttributes, for example) + boolean foundBooleanMin = false; + boolean foundBooleanMax = false; + if (Integer.class.equals(attributableClassField.getType())) { + for (Annotation annotation : attributableClassField.getAnnotations()) { + if (Min.class.equals(annotation.annotationType())) { + foundBooleanMin = ((Min) annotation).value() == 0; + } else if (Max.class.equals(annotation.annotationType())) { + foundBooleanMax = ((Max) annotation).value() == 1; + } + } + } + if (foundBooleanMin && foundBooleanMax) { + if ("true".equalsIgnoreCase(cond.getExpression())) { + cond.setExpression("1"); + } else if ("false".equalsIgnoreCase(cond.getExpression())) { + cond.setExpression("0"); + } + } + + // Deal with Attributable fields representing relationships to other entities + // Only _id and _name are suppored + if (attributableClassField.getType().getAnnotation(Entity.class) != null) { + if (BeanUtils.findDeclaredMethodWithMinimalParameters( + attributableClassField.getType(), "getId") != null) { + + cond.setSchema(cond.getSchema() + "_id"); + } + if (BeanUtils.findDeclaredMethodWithMinimalParameters( + attributableClassField.getType(), "getName") != null) { + + cond.setSchema(cond.getSchema() + "_name"); + } + } + AbstractAttrValue attrValue = attrUtil.newAttrValue(); try { if (cond.getType() != AttributeCond.Type.LIKE && cond.getType() != AttributeCond.Type.ISNULL Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/NotificationValidator.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/NotificationValidator.java?rev=1424852&r1=1424851&r2=1424852&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/NotificationValidator.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/NotificationValidator.java Fri Dec 21 10:31:10 2012 @@ -43,14 +43,14 @@ public class NotificationValidator exten context.buildConstraintViolationWithTemplate("No events").addNode( EntityViolationType.InvalidNotification.toString()).addNode("events").addConstraintViolation(); } - if (!value.getAbout().checkValidity()) { + if (!value.getAbout().isValid()) { isValid = false; context.buildConstraintViolationWithTemplate("Invalid about search condition").addNode( EntityViolationType.InvalidNotification.toString()).addNode("about").addConstraintViolation(); } if (value.getRecipients() != null) { - if (!value.getRecipients().checkValidity() && !value.isSelfAsRecipient()) { + if (!value.getRecipients().isValid() && !value.isSelfAsRecipient()) { isValid = false; context.buildConstraintViolationWithTemplate("Invalid recipients search condition").addNode( Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/RoleController.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/RoleController.java?rev=1424852&r1=1424851&r2=1424852&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/RoleController.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/RoleController.java Fri Dec 21 10:31:10 2012 @@ -215,7 +215,7 @@ public class RoleController extends Abst LOG.debug("Role search called with condition {}", searchCondition); - if (!searchCondition.checkValidity()) { + if (!searchCondition.isValid()) { LOG.error("Invalid search condition: {}", searchCondition); throw new InvalidSearchConditionException(); } @@ -241,7 +241,7 @@ public class RoleController extends Abst public ModelAndView searchCount(@RequestBody final NodeCond searchCondition) throws InvalidSearchConditionException { - if (!searchCondition.checkValidity()) { + if (!searchCondition.isValid()) { LOG.error("Invalid search condition: {}", searchCondition); throw new InvalidSearchConditionException(); } Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java?rev=1424852&r1=1424851&r2=1424852&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java Fri Dec 21 10:31:10 2012 @@ -142,7 +142,7 @@ public class UserController { public ModelAndView searchCount(@RequestBody final NodeCond searchCondition) throws InvalidSearchConditionException { - if (!searchCondition.checkValidity()) { + if (!searchCondition.isValid()) { LOG.error("Invalid search condition: {}", searchCondition); throw new InvalidSearchConditionException(); } @@ -247,7 +247,7 @@ public class UserController { LOG.debug("User search called with condition {}", searchCondition); - if (!searchCondition.checkValidity()) { + if (!searchCondition.isValid()) { LOG.error("Invalid search condition: {}", searchCondition); throw new InvalidSearchConditionException(); } Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/AttributableSearchTest.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/AttributableSearchTest.java?rev=1424852&r1=1424851&r2=1424852&view=diff ============================================================================== --- syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/AttributableSearchTest.java (original) +++ syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/AttributableSearchTest.java Fri Dec 21 10:31:10 2012 @@ -104,11 +104,11 @@ public class AttributableSearchTest { NodeCond subCond = NodeCond.getAndCond(NodeCond.getLeafCond(fullnameLeafCond), NodeCond.getLeafCond( membershipCond)); - assertTrue(subCond.checkValidity()); + assertTrue(subCond.isValid()); NodeCond cond = NodeCond.getAndCond(subCond, NodeCond.getLeafCond(loginDateCond)); - assertTrue(cond.checkValidity()); + assertTrue(cond.isValid()); List<SyncopeUser> users = searchDAO.search(EntitlementUtil.getRoleIds(entitlementDAO.findAll()), cond, AttributableUtil.getInstance(AttributableType.USER)); @@ -123,7 +123,7 @@ public class AttributableSearchTest { fullnameLeafCond.setExpression("fabio.martelli"); final NodeCond cond = NodeCond.getNotLeafCond(fullnameLeafCond); - assertTrue(cond.checkValidity()); + assertTrue(cond.isValid()); final List<SyncopeUser> users = searchDAO.search(EntitlementUtil.getRoleIds(entitlementDAO.findAll()), cond, AttributableUtil.getInstance(AttributableType.USER)); @@ -144,7 +144,7 @@ public class AttributableSearchTest { coolLeafCond.setExpression("true"); final NodeCond cond = NodeCond.getLeafCond(coolLeafCond); - assertTrue(cond.checkValidity()); + assertTrue(cond.isValid()); final List<SyncopeUser> users = searchDAO.search(EntitlementUtil.getRoleIds(entitlementDAO.findAll()), cond, AttributableUtil.getInstance(AttributableType.USER)); @@ -170,11 +170,11 @@ public class AttributableSearchTest { NodeCond subCond = NodeCond.getAndCond(NodeCond.getLeafCond(fullnameLeafCond), NodeCond.getLeafCond( membershipCond)); - assertTrue(subCond.checkValidity()); + assertTrue(subCond.isValid()); NodeCond cond = NodeCond.getAndCond(subCond, NodeCond.getLeafCond(loginDateCond)); - assertTrue(cond.checkValidity()); + assertTrue(cond.isValid()); List<SyncopeUser> users = searchDAO.search(EntitlementUtil.getRoleIds(entitlementDAO.findAll()), cond, 1, 2, AttributableUtil.getInstance(AttributableType.USER)); @@ -239,7 +239,7 @@ public class AttributableSearchTest { NodeCond searchCondition = NodeCond.getAndCond(NodeCond.getNotLeafCond(ws2), NodeCond.getLeafCond(ws1)); - assertTrue(searchCondition.checkValidity()); + assertTrue(searchCondition.isValid()); List<SyncopeUser> users = searchDAO.search( EntitlementUtil.getRoleIds(entitlementDAO.findAll()), searchCondition, @@ -284,7 +284,7 @@ public class AttributableSearchTest { final NodeCond searchCondition = NodeCond.getAndCond(NodeCond.getLeafCond(rolenameLeafCond), NodeCond.getLeafCond(idRightCond)); - assertTrue(searchCondition.checkValidity()); + assertTrue(searchCondition.isValid()); final List<SyncopeRole> matchingRoles = searchDAO.search(EntitlementUtil.getRoleIds(entitlementDAO.findAll()), searchCondition, AttributableUtil.getInstance(AttributableType.ROLE)); @@ -323,7 +323,7 @@ public class AttributableSearchTest { idLeafCond.setExpression("2"); NodeCond searchCondition = NodeCond.getLeafCond(idLeafCond); - assertTrue(searchCondition.checkValidity()); + assertTrue(searchCondition.isValid()); List<SyncopeUser> matchingUsers = searchDAO.search(EntitlementUtil.getRoleIds(entitlementDAO.findAll()), searchCondition, @@ -338,7 +338,7 @@ public class AttributableSearchTest { idLeafCond.setExpression("4"); searchCondition = NodeCond.getNotLeafCond(idLeafCond); - assertTrue(searchCondition.checkValidity()); + assertTrue(searchCondition.isValid()); matchingUsers = searchDAO.search(EntitlementUtil.getRoleIds(entitlementDAO.findAll()), searchCondition, AttributableUtil.getInstance(AttributableType.USER)); @@ -358,7 +358,7 @@ public class AttributableSearchTest { final NodeCond searchCondition = NodeCond.getAndCond(NodeCond.getNotLeafCond(ws2), NodeCond.getNotLeafCond(ws1)); - assertTrue(searchCondition.checkValidity()); + assertTrue(searchCondition.isValid()); final List<SyncopeUser> users = searchDAO.search(EntitlementUtil.getRoleIds(entitlementDAO.findAll()), searchCondition, AttributableUtil.getInstance(AttributableType.USER)); @@ -374,7 +374,7 @@ public class AttributableSearchTest { cond.setExpression("test%"); final NodeCond searchCondition = NodeCond.getLeafCond(cond); - assertTrue(searchCondition.checkValidity()); + assertTrue(searchCondition.isValid()); final List<SyncopeUser> users = searchDAO.search(EntitlementUtil.getRoleIds(entitlementDAO.findAll()), searchCondition, AttributableUtil.getInstance(AttributableType.USER)); @@ -389,7 +389,7 @@ public class AttributableSearchTest { cond.setExpression("%user%"); final NodeCond searchCondition = NodeCond.getLeafCond(cond); - assertTrue(searchCondition.checkValidity()); + assertTrue(searchCondition.isValid()); final List<SyncopeUser> users = searchDAO.search(EntitlementUtil.getRoleIds(entitlementDAO.findAll()), searchCondition, AttributableUtil.getInstance(AttributableType.USER)); Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/NotificationTest.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/NotificationTest.java?rev=1424852&r1=1424851&r2=1424852&view=diff ============================================================================== --- syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/NotificationTest.java (original) +++ syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/NotificationTest.java Fri Dec 21 10:31:10 2012 @@ -48,9 +48,9 @@ public class NotificationTest extends Ab assertNotNull(notification.getEvents()); assertFalse(notification.getEvents().isEmpty()); assertNotNull(notification.getAbout()); - assertTrue(notification.getAbout().checkValidity()); + assertTrue(notification.getAbout().isValid()); assertNotNull(notification.getRecipients()); - assertTrue(notification.getRecipients().checkValidity()); + assertTrue(notification.getRecipients().isValid()); } @Test Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/relationships/AttributableSearchTest.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/relationships/AttributableSearchTest.java?rev=1424852&r1=1424851&r2=1424852&view=diff ============================================================================== --- syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/relationships/AttributableSearchTest.java (original) +++ syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/relationships/AttributableSearchTest.java Fri Dec 21 10:31:10 2012 @@ -68,7 +68,7 @@ public class AttributableSearchTest { coolLeafCond.setExpression("true"); final NodeCond cond = NodeCond.getLeafCond(coolLeafCond); - assertTrue(cond.checkValidity()); + assertTrue(cond.isValid()); final List<SyncopeUser> users = searchDAO.search(EntitlementUtil.getRoleIds(entitlementDAO.findAll()), cond, AttributableUtil.getInstance(AttributableType.USER)); Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/SearchTestITCase.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/SearchTestITCase.java?rev=1424852&r1=1424851&r2=1424852&view=diff ============================================================================== --- syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/SearchTestITCase.java (original) +++ syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/SearchTestITCase.java Fri Dec 21 10:31:10 2012 @@ -26,6 +26,7 @@ import java.util.List; import java.util.Set; import org.apache.syncope.client.search.AttributableCond; import org.apache.syncope.client.search.AttributeCond; +import org.apache.syncope.client.search.EntitlementCond; import org.apache.syncope.client.search.NodeCond; import org.apache.syncope.client.search.ResourceCond; import org.apache.syncope.client.to.RoleTO; @@ -51,7 +52,7 @@ public class SearchTestITCase extends Ab NodeCond searchCondition = NodeCond.getAndCond(NodeCond.getLeafCond(fullnameLeafCond1), NodeCond.getLeafCond( fullnameLeafCond2)); - assertTrue(searchCondition.checkValidity()); + assertTrue(searchCondition.isValid()); List<UserTO> matchedUsers = Arrays.asList(restTemplate.postForObject(BASE_URL + "user/search", searchCondition, UserTO[].class)); @@ -92,7 +93,7 @@ public class SearchTestITCase extends Ab final NodeCond searchCondition = NodeCond.getAndCond(NodeCond.getLeafCond(usernameLeafCond), NodeCond. getLeafCond(idRightCond)); - assertTrue(searchCondition.checkValidity()); + assertTrue(searchCondition.isValid()); final List<UserTO> matchingUsers = Arrays.asList(restTemplate.postForObject(BASE_URL + "user/search", searchCondition, UserTO[].class)); @@ -116,7 +117,7 @@ public class SearchTestITCase extends Ab final NodeCond searchCondition = NodeCond.getAndCond(NodeCond.getLeafCond(rolenameLeafCond), NodeCond.getLeafCond(idRightCond)); - assertTrue(searchCondition.checkValidity()); + assertTrue(searchCondition.isValid()); final List<RoleTO> matchingRoles = Arrays.asList(restTemplate.postForObject(BASE_URL + "role/search", searchCondition, RoleTO[].class)); @@ -137,7 +138,7 @@ public class SearchTestITCase extends Ab NodeCond searchCondition = NodeCond.getAndCond(NodeCond.getNotLeafCond(ws2), NodeCond.getLeafCond(ws1)); - assertTrue(searchCondition.checkValidity()); + assertTrue(searchCondition.isValid()); List<UserTO> matchedUsers = Arrays.asList(restTemplate.postForObject(BASE_URL + "user/search", searchCondition, UserTO[].class)); @@ -167,7 +168,7 @@ public class SearchTestITCase extends Ab NodeCond searchCondition = NodeCond.getAndCond(NodeCond.getLeafCond(fullnameLeafCond1), NodeCond.getLeafCond( fullnameLeafCond2)); - assertTrue(searchCondition.checkValidity()); + assertTrue(searchCondition.isValid()); List<UserTO> matchedUsers = Arrays.asList(restTemplate.postForObject(BASE_URL + "user/search/{page}/{size}", searchCondition, UserTO[].class, 1, 2)); @@ -205,4 +206,55 @@ public class SearchTestITCase extends Ab assertNotNull(count); assertTrue(count > 0); } + + @Test + public void searchByBooleanAttributableCond() { + final AttributableCond cond = new AttributableCond(AttributableCond.Type.EQ); + cond.setSchema("inheritAttributes"); + cond.setExpression("true"); + + final NodeCond searchCondition = NodeCond.getLeafCond(cond); + + final List<RoleTO> matchingRoles = Arrays.asList(restTemplate.postForObject(BASE_URL + "role/search", + searchCondition, RoleTO[].class)); + assertNotNull(matchingRoles); + assertFalse(matchingRoles.isEmpty()); + } + + @Test + public void searchByEntitlement() { + final EntitlementCond cond = new EntitlementCond(); + cond.setExpression("USER"); + + final NodeCond searchCondition = NodeCond.getLeafCond(cond); + assertTrue(searchCondition.isValid()); + + final List<RoleTO> matchingRoles = Arrays.asList(restTemplate.postForObject(BASE_URL + "role/search", + searchCondition, RoleTO[].class)); + assertNotNull(matchingRoles); + assertFalse(matchingRoles.isEmpty()); + } + + @Test + public void searchByRelationshipAttributableCond() { + final AttributableCond userOwnerCond = new AttributableCond(AttributableCond.Type.EQ); + userOwnerCond.setSchema("userOwner"); + userOwnerCond.setExpression("5"); + + final AttributableCond ppolicyCond = new AttributableCond(AttributableCond.Type.ISNOTNULL); + ppolicyCond.setSchema("passwordPolicy"); + + final NodeCond searchCondition = NodeCond.getAndCond(NodeCond.getLeafCond(userOwnerCond), + NodeCond.getLeafCond(ppolicyCond)); + + assertTrue(searchCondition.isValid()); + + final List<RoleTO> matchingRoles = Arrays.asList(restTemplate.postForObject(BASE_URL + "role/search", + searchCondition, RoleTO[].class)); + + assertNotNull(matchingRoles); + assertEquals(1, matchingRoles.size()); + assertEquals("director", matchingRoles.iterator().next().getName()); + assertEquals(6L, matchingRoles.iterator().next().getId()); + } }