syncope-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ilgro...@apache.org
Subject syncope git commit: SYNCOPE-971: Case insensitive search
Date Wed, 23 Nov 2016 16:23:31 GMT
Repository: syncope
Updated Branches:
  refs/heads/2_0_X 831a9ffe3 -> 0e214e004


SYNCOPE-971: Case insensitive search


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/0e214e00
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/0e214e00
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/0e214e00

Branch: refs/heads/2_0_X
Commit: 0e214e0046e3e9940cbe57dacf3f8bf56c1b5f9c
Parents: 831a9ff
Author: gonzalad <adr_gonzalez@yahoo.fr>
Authored: Wed Nov 23 16:22:56 2016 +0100
Committer: Francesco Chicchiriccò <ilgrosso@apache.org>
Committed: Wed Nov 23 16:51:44 2016 +0100

----------------------------------------------------------------------
 .../console/panels/search/SearchUtils.java      |  20 ++-
 .../client/console/wizards/any/Groups.java      |   3 +-
 .../AbstractFiqlSearchConditionBuilder.java     |  10 ++
 .../common/lib/search/SyncopeFiqlParser.java    | 152 +++++++++++++++++++
 .../lib/search/SyncopeFiqlSearchCondition.java  |  59 +++++++
 .../common/lib/search/SyncopeProperty.java      |  10 ++
 .../lib/search/SyncopeFiqlParserTest.java       |  69 +++++++++
 .../api/dao/search/AttributeCond.java           |   2 +
 .../api/search/SearchCondConverter.java         |   6 +-
 .../api/search/SearchCondVisitor.java           |  36 +++--
 .../api/search/SearchCondConverterTest.java     |  55 +++++++
 .../persistence/jpa/dao/JPAAnySearchDAO.java    |  30 +++-
 .../persistence/jpa/inner/AnySearchTest.java    |  86 +++++++++--
 .../src/main/resources/restCXFContext.xml       |   5 +-
 .../src/main/resources/jboss/restCXFContext.xml |   5 +-
 .../apache/syncope/fit/core/SearchITCase.java   |  68 ++++++---
 pom.xml                                         |   2 +-
 17 files changed, 555 insertions(+), 63 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/0e214e00/client/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchUtils.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchUtils.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchUtils.java
index b1fc298..61fca89 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchUtils.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchUtils.java
@@ -30,11 +30,12 @@ import org.apache.cxf.jaxrs.ext.search.ConditionType;
 import org.apache.cxf.jaxrs.ext.search.SearchBean;
 import org.apache.cxf.jaxrs.ext.search.SearchCondition;
 import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
-import org.apache.cxf.jaxrs.ext.search.fiql.FiqlParser;
 import org.apache.syncope.common.lib.search.AbstractFiqlSearchConditionBuilder;
 import org.apache.syncope.common.lib.search.AnyObjectFiqlSearchConditionBuilder;
 import org.apache.syncope.common.lib.search.GroupFiqlSearchConditionBuilder;
 import org.apache.syncope.common.lib.search.SpecialAttr;
+import org.apache.syncope.common.lib.search.SyncopeFiqlParser;
+import org.apache.syncope.common.lib.search.SyncopeFiqlSearchCondition;
 import org.apache.syncope.common.lib.search.SyncopeProperty;
 import org.apache.syncope.common.lib.search.UserFiqlSearchConditionBuilder;
 import org.slf4j.Logger;
@@ -65,7 +66,7 @@ public final class SearchUtils implements Serializable {
         final List<SearchClause> res = new ArrayList<>();
         if (StringUtils.isNotBlank(fiql)) {
             try {
-                FiqlParser<SearchBean> fiqlParser = new FiqlParser<>(
+                SyncopeFiqlParser<SearchBean> fiqlParser = new SyncopeFiqlParser<>(
                         SearchBean.class, AbstractFiqlSearchConditionBuilder.CONTEXTUAL_PROPERTIES);
                 res.addAll(getSearchClauses(fiqlParser.parse(fiql)));
             } catch (Exception e) {
@@ -140,7 +141,16 @@ public final class SearchUtils implements Serializable {
             res.setType(SearchClause.Type.ATTRIBUTE);
         }
 
-        switch (sc.getConditionType()) {
+        ConditionType ct = sc.getConditionType();
+        if (sc instanceof SyncopeFiqlSearchCondition && sc.getConditionType() == ConditionType.CUSTOM) {
+            SyncopeFiqlSearchCondition<SearchBean> sfsc = (SyncopeFiqlSearchCondition<SearchBean>) sc;
+            if (SyncopeFiqlParser.IEQ.equals(sfsc.getOperator())) {
+                ct = ConditionType.EQUALS;
+            } else if (SyncopeFiqlParser.NIEQ.equals(sfsc.getOperator())) {
+                ct = ConditionType.NOT_EQUALS;
+            }
+        }
+        switch (ct) {
             case EQUALS:
                 if (SpecialAttr.RELATIONSHIP_TYPES.toString().equals(property)) {
                     res.setComparator(SpecialAttr.NULL.toString().equals(value)
@@ -273,12 +283,12 @@ public final class SearchUtils implements Serializable {
                                 break;
 
                             case NOT_EQUALS:
-                                condition = property.notEqualTo(clause.getValue());
+                                condition = property.notEqualTolIgnoreCase(clause.getValue());
                                 break;
 
                             case EQUALS:
                             default:
-                                condition = property.equalTo(clause.getValue());
+                                condition = property.equalToIgnoreCase(clause.getValue());
                                 break;
                         }
                     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e214e00/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Groups.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Groups.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Groups.java
index e8aba25..1cdafc8 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Groups.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Groups.java
@@ -128,8 +128,7 @@ public class Groups extends WizardStep implements ICondition {
             }
         }).hideLabel().setOutputMarkupId(true));
 
-        allGroups = groupRestClient.search(
-                templateMode ? "/" : realm, null, -1, -1, new SortParam<>("name", true), null);
+        allGroups = groupRestClient.search("/", null, -1, -1, new SortParam<>("name", true), null);
 
         final Map<String, GroupTO> allGroupsByKey = new LinkedHashMap<>(allGroups.size());
         for (GroupTO group : allGroups) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e214e00/common/lib/src/main/java/org/apache/syncope/common/lib/search/AbstractFiqlSearchConditionBuilder.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/search/AbstractFiqlSearchConditionBuilder.java b/common/lib/src/main/java/org/apache/syncope/common/lib/search/AbstractFiqlSearchConditionBuilder.java
index 0ace0b5..4bf61f3 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/search/AbstractFiqlSearchConditionBuilder.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/search/AbstractFiqlSearchConditionBuilder.java
@@ -109,5 +109,15 @@ public abstract class AbstractFiqlSearchConditionBuilder extends FiqlSearchCondi
             this.result = SpecialAttr.RESOURCES.toString();
             return condition(FiqlParser.NEQ, resource, (Object[]) moreResources);
         }
+
+        @Override
+        public CompleteCondition equalToIgnoreCase(final String value, final String... moreValues) {
+            return condition(SyncopeFiqlParser.IEQ, value, (Object[]) moreValues);
+        }
+
+        @Override
+        public CompleteCondition notEqualTolIgnoreCase(final String literalOrPattern) {
+            return condition(SyncopeFiqlParser.NIEQ, literalOrPattern);
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e214e00/common/lib/src/main/java/org/apache/syncope/common/lib/search/SyncopeFiqlParser.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/search/SyncopeFiqlParser.java b/common/lib/src/main/java/org/apache/syncope/common/lib/search/SyncopeFiqlParser.java
new file mode 100644
index 0000000..dc3c5ae
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/search/SyncopeFiqlParser.java
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.common.lib.search;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.cxf.jaxrs.ext.search.ConditionType;
+import org.apache.cxf.jaxrs.ext.search.SearchBean;
+import org.apache.cxf.jaxrs.ext.search.SearchCondition;
+import org.apache.cxf.jaxrs.ext.search.SearchParseException;
+import org.apache.cxf.jaxrs.ext.search.fiql.FiqlParser;
+
+/**
+ * This parser introduces 2 new operands {@link #IEQ} (case-insensitive equals) and {@link #NIEQ} (case-insensitive
+ * not equals) to the native FIQL operands.
+ *
+ * @param <T> type of search condition.
+ */
+public class SyncopeFiqlParser<T> extends FiqlParser<T> {
+
+    public static final String IEQ = "=~";
+
+    public static final String NIEQ = "!~";
+
+    public SyncopeFiqlParser(
+            final Class<T> tclass,
+            final Map<String, String> contextProperties) {
+
+        this(tclass, contextProperties, null);
+    }
+
+    public SyncopeFiqlParser(
+            final Class<T> tclass,
+            final Map<String, String> contextProperties,
+            final Map<String, String> beanProperties) {
+
+        super(tclass, contextProperties, beanProperties);
+
+        operatorsMap.put(IEQ, ConditionType.CUSTOM);
+        operatorsMap.put(NIEQ, ConditionType.CUSTOM);
+
+        CONDITION_MAP.put(ConditionType.CUSTOM, IEQ);
+        CONDITION_MAP.put(ConditionType.CUSTOM, NIEQ);
+
+        String comparators = GT + "|" + GE + "|" + LT + "|" + LE + "|" + EQ + "|" + NEQ + "|" + IEQ + "|" + NIEQ;
+        String s1 = "[\\p{ASCII}]+(" + comparators + ")";
+        comparatorsPattern = Pattern.compile(s1);
+    }
+
+    @Override
+    protected ASTNode<T> parseComparison(final String expr) throws SearchParseException {
+        Matcher m = comparatorsPattern.matcher(expr);
+        if (m.find()) {
+            String propertyName = expr.substring(0, m.start(1));
+            String operator = m.group(1);
+            String value = expr.substring(m.end(1));
+            if ("".equals(value)) {
+                throw new SearchParseException("Not a comparison expression: " + expr);
+            }
+
+            String name = unwrapSetter(propertyName);
+
+            name = getActualSetterName(name);
+            TypeInfoObject castedValue = parseType(propertyName, name, value);
+            if (castedValue != null) {
+                return new SyncopeComparison(name, operator, castedValue);
+            } else {
+                return null;
+            }
+        } else {
+            throw new SearchParseException("Not a comparison expression: " + expr);
+        }
+    }
+
+    private class SyncopeComparison implements ASTNode<T> {
+
+        private final String name;
+
+        private final String operator;
+
+        private final TypeInfoObject tvalue;
+
+        SyncopeComparison(final String name, final String operator, final TypeInfoObject value) {
+            this.name = name;
+            this.operator = operator;
+            this.tvalue = value;
+        }
+
+        @Override
+        public String toString() {
+            return name + " " + operator + " " + tvalue.getObject()
+                    + " (" + tvalue.getObject().getClass().getSimpleName() + ")";
+        }
+
+        @Override
+        public SearchCondition<T> build() throws SearchParseException {
+            String templateName = getSetter(name);
+            T cond = createTemplate(templateName);
+            ConditionType ct = operatorsMap.get(operator);
+
+            if (isPrimitive(cond)) {
+                return new SyncopeFiqlSearchCondition<>(ct, cond);
+            } else {
+                String templateNameLCase = templateName.toLowerCase();
+                return new SyncopeFiqlSearchCondition<>(Collections.singletonMap(templateNameLCase, ct),
+                        Collections.singletonMap(templateNameLCase, name),
+                        Collections.singletonMap(templateNameLCase, tvalue.getTypeInfo()),
+                        cond, operator);
+            }
+        }
+
+        private boolean isPrimitive(final T pojo) {
+            return pojo.getClass().getName().startsWith("java.lang");
+        }
+
+        @SuppressWarnings("unchecked")
+        private T createTemplate(final String setter) throws SearchParseException {
+            try {
+                if (beanspector != null) {
+                    beanspector.instantiate().setValue(setter, tvalue.getObject());
+                    return beanspector.getBean();
+                } else {
+                    SearchBean bean = (SearchBean) conditionClass.newInstance();
+                    bean.set(setter, tvalue.getObject().toString());
+                    return (T) bean;
+                }
+            } catch (Throwable e) {
+                throw new SearchParseException(e);
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e214e00/common/lib/src/main/java/org/apache/syncope/common/lib/search/SyncopeFiqlSearchCondition.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/search/SyncopeFiqlSearchCondition.java b/common/lib/src/main/java/org/apache/syncope/common/lib/search/SyncopeFiqlSearchCondition.java
new file mode 100644
index 0000000..41e0bac
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/search/SyncopeFiqlSearchCondition.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.common.lib.search;
+
+import java.util.Map;
+
+import org.apache.cxf.jaxrs.ext.search.Beanspector;
+import org.apache.cxf.jaxrs.ext.search.ConditionType;
+import org.apache.cxf.jaxrs.ext.search.SimpleSearchCondition;
+
+/**
+ * Adds support for custom FIQL operators to {@link SimpleSearchCondition}.
+ *
+ * @param <T> type of search condition.
+ */
+public class SyncopeFiqlSearchCondition<T> extends SimpleSearchCondition<T> {
+
+    static {
+        SUPPORTED_TYPES.add(ConditionType.CUSTOM);
+    }
+
+    private String operator;
+
+    public SyncopeFiqlSearchCondition(final ConditionType cType, final T condition) {
+        super(cType, condition);
+    }
+
+    public SyncopeFiqlSearchCondition(
+            final Map<String, ConditionType> getters2operators,
+            final Map<String, String> realGetters,
+            final Map<String, Beanspector.TypeInfo> propertyTypeInfo,
+            final T condition,
+            final String operator) {
+
+        super(getters2operators, realGetters, propertyTypeInfo, condition);
+        this.operator = operator;
+    }
+
+    public String getOperator() {
+        return operator;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e214e00/common/lib/src/main/java/org/apache/syncope/common/lib/search/SyncopeProperty.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/search/SyncopeProperty.java b/common/lib/src/main/java/org/apache/syncope/common/lib/search/SyncopeProperty.java
index f7c4482..2f560c1 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/search/SyncopeProperty.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/search/SyncopeProperty.java
@@ -27,12 +27,22 @@ import org.apache.cxf.jaxrs.ext.search.client.Property;
  */
 public interface SyncopeProperty extends Property {
 
+    /** Is textual property equal to (ignoring case) given literal or matching given pattern? */
+    CompleteCondition equalToIgnoreCase(String value, String... moreValues);
+
+    /** Is textual property different (ignoring case) than given literal or not matching given pattern? */
+    CompleteCondition notEqualTolIgnoreCase(String literalOrPattern);
+
+    /** Is property null? */
     CompleteCondition nullValue();
 
+    /** Is property not null? */
     CompleteCondition notNullValue();
 
+    /** Is user, group or any object owning given resource(s)? */
     CompleteCondition hasResources(String resource, String... moreResources);
 
+    /** Is user, group or any object not owning given resource(s)? */
     CompleteCondition hasNotResources(String resource, String... moreResources);
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e214e00/common/lib/src/test/java/org/apache/syncope/common/lib/search/SyncopeFiqlParserTest.java
----------------------------------------------------------------------
diff --git a/common/lib/src/test/java/org/apache/syncope/common/lib/search/SyncopeFiqlParserTest.java b/common/lib/src/test/java/org/apache/syncope/common/lib/search/SyncopeFiqlParserTest.java
new file mode 100644
index 0000000..8414c41
--- /dev/null
+++ b/common/lib/src/test/java/org/apache/syncope/common/lib/search/SyncopeFiqlParserTest.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.common.lib.search;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.cxf.jaxrs.ext.search.ConditionType;
+import org.apache.cxf.jaxrs.ext.search.SearchBean;
+import org.apache.cxf.jaxrs.ext.search.SearchCondition;
+import org.apache.cxf.jaxrs.ext.search.fiql.FiqlParser;
+import org.junit.Test;
+
+public class SyncopeFiqlParserTest {
+
+    private static final SyncopeFiqlParser<SearchBean> FIQL_PARSER = new SyncopeFiqlParser<>(
+            SearchBean.class, AbstractFiqlSearchConditionBuilder.CONTEXTUAL_PROPERTIES);
+
+    @SuppressWarnings("unchecked")
+    private SyncopeFiqlSearchCondition<SearchBean> parse(final String fiql) {
+        SearchCondition<SearchBean> parsed = FIQL_PARSER.parse(fiql);
+        assertTrue(parsed instanceof SyncopeFiqlSearchCondition);
+        return (SyncopeFiqlSearchCondition) parsed;
+    }
+
+    @Test
+    public void testEqualsIgnoreCase() {
+        SyncopeFiqlSearchCondition<SearchBean> cond = parse("name=~ami*");
+        assertEquals(SyncopeFiqlParser.IEQ, cond.getOperator());
+        assertEquals(ConditionType.CUSTOM, cond.getConditionType());
+        assertEquals("ami*", cond.getCondition().get("name"));
+    }
+
+    @Test
+    public void testNotEqualsIgnoreCase() {
+        SyncopeFiqlSearchCondition<SearchBean> cond = parse("name!~ami*");
+        assertEquals(SyncopeFiqlParser.NIEQ, cond.getOperator());
+        assertEquals(ConditionType.CUSTOM, cond.getConditionType());
+        assertEquals("ami*", cond.getCondition().get("name"));
+    }
+
+    /**
+     * Simple test for ensuring there's no regression.
+     */
+    @Test
+    public void testEquals() {
+        SyncopeFiqlSearchCondition<SearchBean> cond = parse("name==ami*");
+        assertEquals(FiqlParser.EQ, cond.getOperator());
+        assertEquals(ConditionType.EQUALS, cond.getConditionType());
+        assertEquals("ami*", cond.getCondition().get("name"));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e214e00/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AttributeCond.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AttributeCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AttributeCond.java
index 92698b2..b8e2b85 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AttributeCond.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AttributeCond.java
@@ -28,7 +28,9 @@ public class AttributeCond extends AbstractSearchCond {
     public enum Type {
 
         LIKE,
+        ILIKE,
         EQ,
+        IEQ,
         GT,
         LT,
         GE,

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e214e00/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondConverter.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondConverter.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondConverter.java
index ba9255a..f07453f 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondConverter.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondConverter.java
@@ -20,9 +20,9 @@ package org.apache.syncope.core.persistence.api.search;
 
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.apache.cxf.jaxrs.ext.search.SearchBean;
-import org.apache.cxf.jaxrs.ext.search.fiql.FiqlParser;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.search.AbstractFiqlSearchConditionBuilder;
+import org.apache.syncope.common.lib.search.SyncopeFiqlParser;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 
@@ -37,10 +37,10 @@ public final class SearchCondConverter {
      * @param fiqlExpression FIQL string
      * @param realms optional realm to provide to {@link SearchCondVisitor}
      * @return {@link SearchCond} instance for given FIQL expression
-     * @see FiqlParser
+     * @see SyncopeFiqlParser
      */
     public static SearchCond convert(final String fiqlExpression, final String... realms) {
-        FiqlParser<SearchBean> fiqlParser = new FiqlParser<>(
+        SyncopeFiqlParser<SearchBean> fiqlParser = new SyncopeFiqlParser<>(
                 SearchBean.class, AbstractFiqlSearchConditionBuilder.CONTEXTUAL_PROPERTIES);
 
         try {

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e214e00/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondVisitor.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondVisitor.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondVisitor.java
index 76c752b..bd95fe8 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondVisitor.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondVisitor.java
@@ -27,6 +27,8 @@ import org.apache.cxf.jaxrs.ext.search.SearchUtils;
 import org.apache.cxf.jaxrs.ext.search.visitor.AbstractSearchConditionVisitor;
 import org.apache.syncope.common.lib.search.SearchableFields;
 import org.apache.syncope.common.lib.search.SpecialAttr;
+import org.apache.syncope.common.lib.search.SyncopeFiqlParser;
+import org.apache.syncope.common.lib.search.SyncopeFiqlSearchCondition;
 import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
 import org.apache.syncope.core.persistence.api.dao.search.MembershipCond;
 import org.apache.syncope.core.persistence.api.dao.search.ResourceCond;
@@ -75,8 +77,21 @@ public class SearchCondVisitor extends AbstractSearchConditionVisitor<SearchBean
         AttributeCond attributeCond = createAttributeCond(name);
         attributeCond.setExpression(value);
 
+        ConditionType ct = sc.getConditionType();
+        if (sc instanceof SyncopeFiqlSearchCondition && sc.getConditionType() == ConditionType.CUSTOM) {
+            SyncopeFiqlSearchCondition<SearchBean> sfsc = (SyncopeFiqlSearchCondition<SearchBean>) sc;
+            if (SyncopeFiqlParser.IEQ.equals(sfsc.getOperator())) {
+                ct = ConditionType.EQUALS;
+            } else if (SyncopeFiqlParser.NIEQ.equals(sfsc.getOperator())) {
+                ct = ConditionType.NOT_EQUALS;
+            } else {
+                throw new IllegalArgumentException(
+                        String.format("Condition type %s is not supported", sfsc.getOperator()));
+            }
+        }
+
         SearchCond leaf;
-        switch (sc.getConditionType()) {
+        switch (ct) {
             case EQUALS:
             case NOT_EQUALS:
                 if (specialAttrName == null) {
@@ -84,9 +99,13 @@ public class SearchCondVisitor extends AbstractSearchConditionVisitor<SearchBean
                         attributeCond.setType(AttributeCond.Type.ISNULL);
                         attributeCond.setExpression(null);
                     } else if (value.indexOf('%') == -1) {
-                        attributeCond.setType(AttributeCond.Type.EQ);
+                        attributeCond.setType(sc.getConditionType() == ConditionType.CUSTOM
+                                ? AttributeCond.Type.IEQ
+                                : AttributeCond.Type.EQ);
                     } else {
-                        attributeCond.setType(AttributeCond.Type.LIKE);
+                        attributeCond.setType(sc.getConditionType() == ConditionType.CUSTOM
+                                ? AttributeCond.Type.ILIKE
+                                : AttributeCond.Type.LIKE);
                     }
 
                     leaf = SearchCond.getLeafCond(attributeCond);
@@ -133,7 +152,7 @@ public class SearchCondVisitor extends AbstractSearchConditionVisitor<SearchBean
                             assignableCond.setRealmFullPath(realm);
                             leaf = SearchCond.getLeafCond(assignableCond);
                             break;
-                            
+
                         case MEMBER:
                             MemberCond memberCond = new MemberCond();
                             memberCond.setMember(value);
@@ -145,14 +164,12 @@ public class SearchCondVisitor extends AbstractSearchConditionVisitor<SearchBean
                                     String.format("Special attr name %s is not supported", specialAttrName));
                     }
                 }
-                if (sc.getConditionType() == ConditionType.NOT_EQUALS) {
+                if (ct == ConditionType.NOT_EQUALS) {
                     if (leaf.getAttributeCond() != null
                             && leaf.getAttributeCond().getType() == AttributeCond.Type.ISNULL) {
 
                         leaf.getAttributeCond().setType(AttributeCond.Type.ISNOTNULL);
-                    } else if (leaf.getAnyCond() != null
-                            && leaf.getAnyCond().getType() == AnyCond.Type.ISNULL) {
-
+                    } else if (leaf.getAnyCond() != null && leaf.getAnyCond().getType() == AnyCond.Type.ISNULL) {
                         leaf.getAnyCond().setType(AttributeCond.Type.ISNOTNULL);
                     } else {
                         leaf = SearchCond.getNotLeafCond(leaf);
@@ -181,8 +198,7 @@ public class SearchCondVisitor extends AbstractSearchConditionVisitor<SearchBean
                 break;
 
             default:
-                throw new IllegalArgumentException(
-                        String.format("Condition type %s is not supported", sc.getConditionType().name()));
+                throw new IllegalArgumentException(String.format("Condition type %s is not supported", ct.name()));
         }
 
         return leaf;

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e214e00/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/SearchCondConverterTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/SearchCondConverterTest.java b/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/SearchCondConverterTest.java
index c5306dd..144d42d 100644
--- a/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/SearchCondConverterTest.java
+++ b/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/SearchCondConverterTest.java
@@ -53,6 +53,34 @@ public class SearchCondConverterTest {
     }
 
     @Test
+    public void ieq() {
+        String fiqlExpression = new UserFiqlSearchConditionBuilder().
+                is("username").equalToIgnoreCase("rossini").query();
+        assertEquals("username=~rossini", fiqlExpression);
+
+        AnyCond attrCond = new AnyCond(AttributeCond.Type.IEQ);
+        attrCond.setSchema("username");
+        attrCond.setExpression("rossini");
+        SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
+
+        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+    }
+
+    @Test
+    public void nieq() {
+        String fiqlExpression = new UserFiqlSearchConditionBuilder().
+                is("username").notEqualTolIgnoreCase("rossini").query();
+        assertEquals("username!~rossini", fiqlExpression);
+
+        AnyCond attrCond = new AnyCond(AttributeCond.Type.IEQ);
+        attrCond.setSchema("username");
+        attrCond.setExpression("rossini");
+        SearchCond simpleCond = SearchCond.getNotLeafCond(attrCond);
+
+        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+    }
+
+    @Test
     public void like() {
         String fiqlExpression = new UserFiqlSearchConditionBuilder().is("username").equalTo("ros*").query();
         assertEquals("username==ros*", fiqlExpression);
@@ -66,6 +94,33 @@ public class SearchCondConverterTest {
     }
 
     @Test
+    public void ilike() {
+        String fiqlExpression = new UserFiqlSearchConditionBuilder().is("username").
+                equalToIgnoreCase("ros*").query();
+        assertEquals("username=~ros*", fiqlExpression);
+
+        AttributeCond attrCond = new AnyCond(AttributeCond.Type.ILIKE);
+        attrCond.setSchema("username");
+        attrCond.setExpression("ros%");
+        SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
+
+        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+    }
+
+    @Test
+    public void nilike() {
+        String fiqlExpression = new UserFiqlSearchConditionBuilder().is("username").notEqualTolIgnoreCase("ros*").query();
+        assertEquals("username!~ros*", fiqlExpression);
+
+        AttributeCond attrCond = new AnyCond(AttributeCond.Type.ILIKE);
+        attrCond.setSchema("username");
+        attrCond.setExpression("ros%");
+        SearchCond simpleCond = SearchCond.getNotLeafCond(attrCond);
+
+        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+    }
+
+    @Test
     public void isNull() {
         String fiqlExpression = new UserFiqlSearchConditionBuilder().is("loginDate").nullValue().query();
         assertEquals("loginDate==" + SpecialAttr.NULL, fiqlExpression);

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e214e00/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
index 745d82a..1513f4f 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
@@ -703,7 +703,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO
         if (SyncopeConstants.UUID_PATTERN.matcher(cond.getMember()).matches()) {
             memberKey = cond.getMember();
         } else {
-            Any member = userDAO.findByUsername(cond.getMember());
+            Any<?> member = userDAO.findByUsername(cond.getMember());
             if (member == null) {
                 member = anyObjectDAO.findByName(cond.getMember());
             }
@@ -745,9 +745,16 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO
             final PlainSchema schema, final AttributeCond cond, final boolean not,
             final List<Object> parameters, final SearchSupport svs) {
 
-        String column = (cond instanceof AnyCond)
-                ? cond.getSchema()
-                : "' AND " + svs.fieldName(schema.getType());
+        // activate ignoreCase only for EQ and LIKE operators
+        boolean ignoreCase = AttributeCond.Type.ILIKE == cond.getType() || AttributeCond.Type.IEQ == cond.getType();
+        
+        String column = (cond instanceof AnyCond)  ? cond.getSchema() :  svs.fieldName(schema.getType());
+        if (ignoreCase) {
+            column = "LOWER (" + column + ")";
+        }
+        if (!(cond instanceof AnyCond)) {
+            column = "' AND " + column;
+        }
 
         switch (cond.getType()) {
 
@@ -763,13 +770,19 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO
                         : " IS NOT NULL");
                 break;
 
+            case ILIKE:
             case LIKE:
                 if (schema.getType() == AttrSchemaType.String || schema.getType() == AttrSchemaType.Enum) {
                     query.append(column);
                     if (not) {
                         query.append(" NOT ");
                     }
-                    query.append(" LIKE ?").append(setParameter(parameters, cond.getExpression()));
+                    query.append(" LIKE ");
+                    if (ignoreCase) {
+                        query.append("LOWER(?").append(setParameter(parameters, cond.getExpression())).append(')');
+                    } else {
+                        query.append('?').append(setParameter(parameters, cond.getExpression()));
+                    }
                 } else {
                     if (!(cond instanceof AnyCond)) {
                         query.append("' AND");
@@ -779,6 +792,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO
                 }
                 break;
 
+            case IEQ:
             case EQ:
                 query.append(column);
                 if (not) {
@@ -786,7 +800,11 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO
                 } else {
                     query.append('=');
                 }
-                query.append('?').append(setParameter(parameters, attrValue.getValue()));
+                if (ignoreCase) {
+                    query.append("LOWER(?").append(setParameter(parameters, attrValue.getValue())).append(')');
+                } else {
+                    query.append('?').append(setParameter(parameters, attrValue.getValue()));
+                }
                 break;
 
             case GE:

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e214e00/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java
index e661d43..1e59280 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java
@@ -154,6 +154,33 @@ public class AnySearchTest extends AbstractTest {
     }
 
     @Test
+    public void searchCaseInsensitiveWithLikeCondition() {
+        AttributeCond fullnameLeafCond = new AttributeCond(AttributeCond.Type.ILIKE);
+        fullnameLeafCond.setSchema("fullname");
+        fullnameLeafCond.setExpression("%O%");
+
+        MembershipCond groupCond = new MembershipCond();
+        groupCond.setGroup("root");
+
+        AttributeCond loginDateCond = new AttributeCond(AttributeCond.Type.EQ);
+        loginDateCond.setSchema("loginDate");
+        loginDateCond.setExpression("2009-05-26");
+
+        SearchCond subCond = SearchCond.getAndCond(
+                SearchCond.getLeafCond(fullnameLeafCond), SearchCond.getLeafCond(groupCond));
+
+        assertTrue(subCond.isValid());
+
+        SearchCond cond = SearchCond.getAndCond(subCond, SearchCond.getLeafCond(loginDateCond));
+
+        assertTrue(cond.isValid());
+
+        List<User> users = searchDAO.search(cond, AnyTypeKind.USER);
+        assertNotNull(users);
+        assertEquals(1, users.size());
+    }
+
+    @Test
     public void searchWithNotCondition() {
         AttributeCond fullnameLeafCond = new AttributeCond(AttributeCond.Type.EQ);
         fullnameLeafCond.setSchema("fullname");
@@ -175,6 +202,27 @@ public class AnySearchTest extends AbstractTest {
     }
 
     @Test
+    public void searchCaseInsensitiveWithNotCondition() {
+        AttributeCond fullnameLeafCond = new AttributeCond(AttributeCond.Type.IEQ);
+        fullnameLeafCond.setSchema("fullname");
+        fullnameLeafCond.setExpression("giuseppe verdi");
+
+        SearchCond cond = SearchCond.getNotLeafCond(fullnameLeafCond);
+        assertTrue(cond.isValid());
+
+        List<User> users = searchDAO.search(cond, AnyTypeKind.USER);
+        assertNotNull(users);
+        assertEquals(4, users.size());
+
+        Set<String> ids = new HashSet<>(users.size());
+        for (User user : users) {
+            ids.add(user.getKey());
+        }
+        assertTrue(ids.contains("1417acbe-cbf6-4277-9372-e75e04f97000"));
+        assertTrue(ids.contains("b3cbc78d-32e6-4bd4-92e0-bbe07566a2ee"));
+    }
+
+    @Test
     public void searchByBoolean() {
         AttributeCond coolLeafCond = new AttributeCond(AttributeCond.Type.EQ);
         coolLeafCond.setSchema("cool");
@@ -361,6 +409,26 @@ public class AnySearchTest extends AbstractTest {
     }
 
     @Test
+    public void searchByUsernameAndFullnameIgnoreCase() {
+        AnyCond usernameLeafCond = new AnyCond(AnyCond.Type.IEQ);
+        usernameLeafCond.setSchema("username");
+        usernameLeafCond.setExpression("RoSsini");
+
+        AttributeCond idRightCond = new AttributeCond(AttributeCond.Type.ILIKE);
+        idRightCond.setSchema("fullname");
+        idRightCond.setExpression("gIuseppe v%");
+
+        SearchCond searchCondition = SearchCond.getOrCond(
+                SearchCond.getLeafCond(usernameLeafCond),
+                SearchCond.getLeafCond(idRightCond));
+
+        List<User> matchingUsers = searchDAO.search(
+                searchCondition, AnyTypeKind.USER);
+        assertNotNull(matchingUsers);
+        assertEquals(2, matchingUsers.size());
+    }
+
+    @Test
     public void searchByKey() {
         AnyCond idLeafCond = new AnyCond(AnyCond.Type.EQ);
         idLeafCond.setSchema("id");
@@ -602,27 +670,27 @@ public class AnySearchTest extends AbstractTest {
         assertNotNull(count);
         assertTrue(count > 0);
     }
-    
+
     @Test
     public void issueSYNCOPE929() {
         AttributeCond rossiniCond = new AttributeCond(AttributeCond.Type.EQ);
         rossiniCond.setSchema("surname");
         rossiniCond.setExpression("Rossini");
-        
+
         AttributeCond genderCond = new AttributeCond(AttributeCond.Type.EQ);
         genderCond.setSchema("gender");
         genderCond.setExpression("M");
 
-        SearchCond orCond = 
-            SearchCond.getOrCond(SearchCond.getLeafCond(rossiniCond),
-                                 SearchCond.getLeafCond(genderCond));
-        
+        SearchCond orCond =
+                SearchCond.getOrCond(SearchCond.getLeafCond(rossiniCond),
+                        SearchCond.getLeafCond(genderCond));
+
         AttributeCond belliniCond = new AttributeCond(AttributeCond.Type.EQ);
         belliniCond.setSchema("surname");
         belliniCond.setExpression("Bellini");
-        
-        SearchCond searchCond = 
-            SearchCond.getAndCond(orCond, SearchCond.getLeafCond(belliniCond));
+
+        SearchCond searchCond =
+                SearchCond.getAndCond(orCond, SearchCond.getLeafCond(belliniCond));
 
         List<User> users = searchDAO.search(searchCond, AnyTypeKind.USER);
         assertNotNull(users);

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e214e00/core/rest-cxf/src/main/resources/restCXFContext.xml
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/resources/restCXFContext.xml b/core/rest-cxf/src/main/resources/restCXFContext.xml
index 5daa96a..c918942 100644
--- a/core/rest-cxf/src/main/resources/restCXFContext.xml
+++ b/core/rest-cxf/src/main/resources/restCXFContext.xml
@@ -120,8 +120,9 @@ under the License.
   <jaxrs:server id="restContainer" address="/"
                 basePackages="org.apache.syncope.common.rest.api.service, org.apache.syncope.core.rest.cxf.service" 
                 staticSubresourceResolution="true">
-    <jaxrs:properties> 
-      <entry key="search.lax.property.match" value="true"/> 
+    <jaxrs:properties>
+      <entry key="search.parser.class" value="org.apache.syncope.common.lib.search.SyncopeFiqlParser"/>
+      <entry key="search.lax.property.match" value="true"/>
       <entry key="convert.wadl.resources.to.dom" value="false"/>
     </jaxrs:properties> 
     <jaxrs:inInterceptors>

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e214e00/fit/core-reference/src/main/resources/jboss/restCXFContext.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/jboss/restCXFContext.xml b/fit/core-reference/src/main/resources/jboss/restCXFContext.xml
index 7a9bed5..f64da85 100644
--- a/fit/core-reference/src/main/resources/jboss/restCXFContext.xml
+++ b/fit/core-reference/src/main/resources/jboss/restCXFContext.xml
@@ -132,8 +132,9 @@ under the License.
   <jaxrs:server id="restContainer" address="/"
                 basePackages="org.apache.syncope.common.rest.api.service, org.apache.syncope.core.rest.cxf.service" 
                 staticSubresourceResolution="true">
-    <jaxrs:properties> 
-      <entry key="search.lax.property.match" value="true"/> 
+    <jaxrs:properties>
+      <entry key="search.parser.class" value="org.apache.syncope.common.lib.search.SyncopeFiqlParser"/>
+      <entry key="search.lax.property.match" value="true"/>
       <entry key="convert.wadl.resources.to.dom" value="false"/>
     </jaxrs:properties> 
     <jaxrs:inInterceptors>

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e214e00/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
index c5ab231..b7f6558 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
@@ -47,8 +47,8 @@ public class SearchITCase extends AbstractITCase {
         // LIKE
         PagedResult<UserTO> matchingUsers = userService.search(
                 new AnyQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().
-                        is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query()).build());
+                        fiql(SyncopeClient.getUserSearchConditionBuilder().
+                                is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query()).build());
         assertNotNull(matchingUsers);
         assertFalse(matchingUsers.getResult().isEmpty());
 
@@ -74,11 +74,31 @@ public class SearchITCase extends AbstractITCase {
     }
 
     @Test
+    public void searchUserIgnoreCase() {
+        PagedResult<UserTO> matchingUsers = userService.search(
+                new AnyQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                        fiql(SyncopeClient.getUserSearchConditionBuilder().
+                                is("username").equalToIgnoreCase("RoSsINI").and("key").lessThan(2).query()).build());
+        assertNotNull(matchingUsers);
+        assertEquals(1, matchingUsers.getResult().size());
+        assertEquals("rossini", matchingUsers.getResult().iterator().next().getUsername());
+        assertEquals("1417acbe-cbf6-4277-9372-e75e04f97000", matchingUsers.getResult().iterator().next().getKey());
+
+        matchingUsers = userService.search(
+                new AnyQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                        fiql("(fullname=~*oSsINi)").page(1).size(2).build());
+        assertNotNull(matchingUsers);
+        assertEquals(1, matchingUsers.getResult().size());
+        assertEquals("rossini", matchingUsers.getResult().iterator().next().getUsername());
+        assertEquals("1417acbe-cbf6-4277-9372-e75e04f97000", matchingUsers.getResult().iterator().next().getKey());
+    }
+
+    @Test
     public void searchByUsernameAndKey() {
         PagedResult<UserTO> matchingUsers = userService.search(
                 new AnyQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().
-                        is("username").equalTo("rossini").and("key").lessThan(2).query()).build());
+                        fiql(SyncopeClient.getUserSearchConditionBuilder().
+                                is("username").equalTo("rossini").and("key").lessThan(2).query()).build());
         assertNotNull(matchingUsers);
         assertEquals(1, matchingUsers.getResult().size());
         assertEquals("rossini", matchingUsers.getResult().iterator().next().getUsername());
@@ -101,8 +121,8 @@ public class SearchITCase extends AbstractITCase {
     public void searchByGroup() {
         PagedResult<UserTO> matchingUsers = userService.search(
                 new AnyQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().inGroups("root").query()).
-                build());
+                        fiql(SyncopeClient.getUserSearchConditionBuilder().inGroups("root").query()).
+                        build());
         assertNotNull(matchingUsers);
         assertFalse(matchingUsers.getResult().isEmpty());
 
@@ -124,8 +144,8 @@ public class SearchITCase extends AbstractITCase {
 
         PagedResult<UserTO> matchingUsers = userService.search(
                 new AnyQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().inGroups(group.getKey()).query()).
-                build());
+                        fiql(SyncopeClient.getUserSearchConditionBuilder().inGroups(group.getKey()).query()).
+                        build());
         assertNotNull(matchingUsers);
         assertFalse(matchingUsers.getResult().isEmpty());
 
@@ -142,8 +162,8 @@ public class SearchITCase extends AbstractITCase {
     public void searchByRole() {
         PagedResult<UserTO> matchingUsers = userService.search(
                 new AnyQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().inRoles("Other").query()).
-                build());
+                        fiql(SyncopeClient.getUserSearchConditionBuilder().inRoles("Other").query()).
+                        build());
         assertNotNull(matchingUsers);
         assertFalse(matchingUsers.getResult().isEmpty());
 
@@ -166,8 +186,8 @@ public class SearchITCase extends AbstractITCase {
 
         PagedResult<UserTO> matchingUsers = userService.search(
                 new AnyQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().inRoles(role.getKey()).query()).
-                build());
+                        fiql(SyncopeClient.getUserSearchConditionBuilder().inRoles(role.getKey()).query()).
+                        build());
         assertNotNull(matchingUsers);
         assertFalse(matchingUsers.getResult().isEmpty());
 
@@ -184,8 +204,8 @@ public class SearchITCase extends AbstractITCase {
     public void searchUserByResourceName() {
         PagedResult<UserTO> matchingUsers = userService.search(
                 new AnyQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().hasResources(RESOURCE_NAME_MAPPINGS2).query()).
-                build());
+                        fiql(SyncopeClient.getUserSearchConditionBuilder().hasResources(RESOURCE_NAME_MAPPINGS2).query()).
+                        build());
         assertNotNull(matchingUsers);
         assertFalse(matchingUsers.getResult().isEmpty());
 
@@ -203,8 +223,9 @@ public class SearchITCase extends AbstractITCase {
         // LIKE
         PagedResult<UserTO> matchingUsers = userService.search(
                 new AnyQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().
-                        is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query()).page(1).size(2).build());
+                        fiql(SyncopeClient.getUserSearchConditionBuilder().
+                                is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query()).page(1).size(2).
+                        build());
         assertNotNull(matchingUsers);
 
         assertFalse(matchingUsers.getResult().isEmpty());
@@ -259,7 +280,7 @@ public class SearchITCase extends AbstractITCase {
     public void nested() {
         PagedResult<UserTO> matchingUsers = userService.search(
                 new AnyQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql("((fullname==*o*,fullname==*i*);$resources!=ws-target-resource-1)").page(1).size(2).build());
+                        fiql("((fullname==*o*,fullname==*i*);$resources!=ws-target-resource-1)").page(1).size(2).build());
         assertNotNull(matchingUsers);
 
         assertFalse(matchingUsers.getResult().isEmpty());
@@ -415,8 +436,8 @@ public class SearchITCase extends AbstractITCase {
     public void orderBy() {
         PagedResult<UserTO> matchingUsers = userService.search(
                 new AnyQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().is("userId").equalTo("*@apache.org").query()).
-                orderBy(SyncopeClient.getOrderByClauseBuilder().asc("status").desc("firstname").build()).build());
+                        fiql(SyncopeClient.getUserSearchConditionBuilder().is("userId").equalTo("*@apache.org").query()).
+                        orderBy(SyncopeClient.getOrderByClauseBuilder().asc("status").desc("firstname").build()).build());
         assertNotNull(matchingUsers);
 
         assertFalse(matchingUsers.getResult().isEmpty());
@@ -443,12 +464,13 @@ public class SearchITCase extends AbstractITCase {
                 getTotalCount();
         assertEquals(nonOrdered, orderedByNullable);
     }
-    
+
     @Test
     public void issueSYNCOPE929() {
-        PagedResult<UserTO> matchingUsers = userService.search(new AnyQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql("(surname==Rossini,gender==M);surname==Bellini").build());
-        
+        PagedResult<UserTO> matchingUsers = userService.search(
+                new AnyQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                        fiql("(surname==Rossini,gender==M);surname==Bellini").build());
+
         assertNotNull(matchingUsers);
 
         assertFalse(matchingUsers.getResult().isEmpty());

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e214e00/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 0372fb5..390e99c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -356,7 +356,7 @@ under the License.
     <connid.ldap.version>1.5.1</connid.ldap.version>
     <connid.ad.version>1.3.2</connid.ad.version>
 
-    <cxf.version>3.1.8</cxf.version>
+    <cxf.version>3.1.9-SNAPSHOT</cxf.version>
 
     <camel.version>2.17.3</camel.version>	
 


Mime
View raw message