Skip to content

Commit

Permalink
Fixed serialization/parsing of OrgFilter. Hopefully fixing MID-2400.
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed Dec 17, 2015
1 parent a49a323 commit a9cd540
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 7 deletions.
Expand Up @@ -110,6 +110,7 @@ public class QueryConvertor {
public static final QName KEY_FILTER_ORG_REF = new QName(NS_QUERY, "orgRef");
public static final QName KEY_FILTER_ORG_REF_OID = new QName(NS_QUERY, "oid");
public static final QName KEY_FILTER_ORG_SCOPE = new QName(NS_QUERY, "scope");
public static final QName KEY_FILTER_ORG_IS_ROOT = new QName(NS_QUERY, "isRoot");
public static final QName KEY_FILTER_ORG_MIN_DEPTH = new QName(NS_QUERY, "minDepth");
public static final QName KEY_FILTER_ORG_MAX_DEPTH = new QName(NS_QUERY, "maxDepth");

Expand Down Expand Up @@ -543,6 +544,15 @@ private static <C extends Containerable> SubstringFilter parseSubstringFilter(XN

private static <C extends Containerable> OrgFilter parseOrgFilter(XNode xnode, PrismContainerDefinition<C> pcd, boolean preliminaryParsingOnly, PrismContext prismContext) throws SchemaException {
MapXNode xmap = toMap(xnode);

if (Boolean.TRUE.equals(xmap.getParsedPrimitiveValue(KEY_FILTER_ORG_IS_ROOT, DOMUtil.XSD_BOOLEAN))) {
// TODO check if other content is present
if (preliminaryParsingOnly) {
return null;
} else {
return OrgFilter.createRootOrg();
}
}

XNode xorgrefnode = xmap.get(KEY_FILTER_ORG_REF);
if (xorgrefnode == null) {
Expand All @@ -556,8 +566,11 @@ private static <C extends Containerable> OrgFilter parseOrgFilter(XNode xnode, P

XsdTypeMapper.getTypeFromClass(Scope.class);

String scopeString = xorgrefmap.getParsedPrimitiveValue(KEY_FILTER_ORG_SCOPE, DOMUtil.XSD_STRING);
Scope scope = Scope.valueOf(scopeString);
String scopeString = xorgrefmap.getParsedPrimitiveValue(KEY_FILTER_ORG_SCOPE, DOMUtil.XSD_STRING); // original (in my opinion incorrect) place
if (scopeString == null) {
scopeString = xmap.getParsedPrimitiveValue(KEY_FILTER_ORG_SCOPE, DOMUtil.XSD_STRING); // here it is placed by the serializer
}
Scope scope = scopeString != null ? Scope.valueOf(scopeString) : null;

if (preliminaryParsingOnly) {
return null;
Expand All @@ -579,6 +592,13 @@ private static MapXNode toMap(XNode xnode) throws SchemaException {
}
return (MapXNode)xnode;
}

private static PrimitiveXNode toPrimitive(XNode xnode, XNode context) throws SchemaException {
if (!(xnode instanceof PrimitiveXNode)) {
throw new SchemaException("Cannot parse filter from "+context+ ": This should be a primitive: "+xnode);
}
return (PrimitiveXNode)xnode;
}

private static ItemPath getPath(MapXNode xmap, PrismContext prismContext) throws SchemaException {
XNode xnode = xmap.get(KEY_FILTER_EQUAL_PATH);
Expand Down Expand Up @@ -832,8 +852,18 @@ private static MapXNode serializeNoneFilter(NoneFilter filter, XNodeSerializer x

private static MapXNode serializeOrgFilter(OrgFilter filter, XNodeSerializer xnodeSerializer) {
MapXNode map = new MapXNode();
map.put(KEY_FILTER_ORG_REF_OID, createPrimitiveXNode(filter.getOrgRef().getOid(), DOMUtil.XSD_STRING));
map.put(KEY_FILTER_ORG_SCOPE, createPrimitiveXNode(filter.getScope().name(), DOMUtil.XSD_STRING));

if (filter.getOrgRef() != null) {
MapXNode orgRefMap = new MapXNode();
orgRefMap.put(KEY_FILTER_ORG_REF_OID, createPrimitiveXNode(filter.getOrgRef().getOid(), DOMUtil.XSD_STRING));
map.put(KEY_FILTER_ORG_REF, orgRefMap);
}
if (filter.getScope() != null) {
map.put(KEY_FILTER_ORG_SCOPE, createPrimitiveXNode(filter.getScope().name(), DOMUtil.XSD_STRING));
}
if (filter.isRoot()) {
map.put(KEY_FILTER_ORG_IS_ROOT, createPrimitiveXNode(Boolean.TRUE, DOMUtil.XSD_BOOLEAN));
}

MapXNode xtypeFilter= new MapXNode();
xtypeFilter.put(KEY_FILTER_ORG, map);
Expand Down
Expand Up @@ -25,6 +25,8 @@
import com.evolveum.midpoint.prism.query.ObjectFilter;
import com.evolveum.midpoint.prism.query.ObjectQuery;
import com.evolveum.midpoint.prism.schema.SchemaRegistry;
import com.evolveum.midpoint.prism.xnode.MapXNode;
import com.evolveum.midpoint.prism.xnode.RootXNode;
import com.evolveum.midpoint.util.DOMUtil;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.logging.Trace;
Expand Down Expand Up @@ -222,8 +224,18 @@ public static void displayQuery(ObjectQuery query) {
}
}

public static void displayQueryType(QueryType queryType) throws SchemaException {
//LOGGER.info(DOMUtil.serializeDOMToString(queryType.getFilter().getFilterClause()));
LOGGER.info(queryType.getFilter().getFilterClauseXNode().debugDump());
public static void displayQueryType(QueryType queryType) throws SchemaException {
displaySearchFilterType(queryType.getFilter());
}

public static void displaySearchFilterType(SearchFilterType filterType) throws SchemaException {
MapXNode mapXNode = filterType.getFilterClauseXNode();

String dumpX = mapXNode.debugDump();
LOGGER.info(dumpX);
System.out.println(dumpX);

String dumpXml = prismContext.serializeXNodeToString(new RootXNode(new QName("query"), mapXNode), PrismContext.LANG_XML);
System.out.println(dumpXml);
}
}
Expand Up @@ -25,10 +25,17 @@

import javax.xml.namespace.QName;

import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.parser.DomParser;
import com.evolveum.midpoint.prism.parser.QueryConvertor;
import com.evolveum.midpoint.prism.query.OrgFilter;
import com.evolveum.midpoint.prism.query.builder.QueryBuilder;
import com.evolveum.midpoint.prism.util.PrismTestUtil;
import com.evolveum.midpoint.prism.util.PrismUtil;

import com.evolveum.midpoint.prism.xnode.RootXNode;
import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType;
import org.apache.commons.lang.StringUtils;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Test;
import org.w3c.dom.Element;
Expand Down Expand Up @@ -407,4 +414,119 @@ public void testConvertQueryNullFilter() throws Exception {
assertEquals(new Integer(10), paging.getMaxSize());

}

@Test
public void test100OrgFilterRoot() throws Exception {
displayTestTitle("test100OrgFilterRoot");

ObjectQuery query = QueryBuilder.queryFor(OrgType.class, getPrismContext()).isRoot().build();
String expected = "<q:org> <q:isRoot>true</q:isRoot> </q:org>";

checkQuery(query, expected);
}

protected void checkQuery(ObjectQuery query, String expected) throws Exception {
displayQuery(query);

QueryType queryType = toQueryType(query);
displayQueryType(queryType);

assertXml(queryType, expected);

ObjectQuery query2 = toObjectQuery(OrgType.class, queryType);
displayQuery(query2);

// primitive way of comparing queries
assertEquals("Reparsed query is not as original one", query.toString(), query2.toString());

QueryType queryType2 = toQueryType(query2);
displayQueryType(queryType2);

assertEquals("Reserialized query type is not as original one", queryType, queryType2);
}

@Test
public void test110OrgFilterSubtree() throws Exception {
displayTestTitle("test110OrgFilterSubtree");

ObjectQuery query = QueryBuilder.queryFor(OrgType.class, getPrismContext()).isChildOf("111").build();
displayQuery(query);

String expected = "<q:org>\n" +
" <q:orgRef>\n" +
" <q:oid>111</q:oid>\n" +
" </q:orgRef>\n" +
" <q:scope>SUBTREE</q:scope>\n" +
" </q:org>";

checkQuery(query, expected);
}

@Test
public void test120OrgFilterDirect() throws Exception {
displayTestTitle("test120OrgFilterDirect");

ObjectQuery query = QueryBuilder.queryFor(OrgType.class, getPrismContext()).isDirectChildOf("222").build();
displayQuery(query);

String expected = "<q:org>\n" +
" <q:orgRef>\n" +
" <q:oid>222</q:oid>\n" +
" </q:orgRef>\n" +
" <q:scope>ONE_LEVEL</q:scope>\n" +
" </q:org>";

checkQuery(query, expected);
}

@Test
public void test130OrgFilterDefaultScope() throws Exception {
displayTestTitle("test130OrgFilterDefaultScope");

String filterText = "<?xml version='1.0'?><filter><org>\n" +
" <orgRef>\n" +
" <oid>333</oid>\n" +
" </orgRef>\n" +
" </org></filter>";

SearchFilterType filterType = getPrismContext().parseAtomicValue(filterText, SearchFilterType.COMPLEX_TYPE, PrismContext.LANG_XML);
displaySearchFilterType(filterType);

ObjectFilter filter = QueryConvertor.parseFilter(filterType, OrgType.class, getPrismContext());
ObjectQuery query = ObjectQuery.createObjectQuery(filter);

ObjectQuery expectedQuery = QueryBuilder.queryFor(OrgType.class, getPrismContext()).isChildOf("333").build();
// primitive way of comparing queries
assertEquals("Parsed query is wrong", expectedQuery.toString(), query.toString());

// now reserialize the parsed query and compare with XML
String expected = "<q:org>\n" +
" <q:orgRef>\n" +
" <q:oid>333</q:oid>\n" +
" </q:orgRef>\n" +
" <q:scope>SUBTREE</q:scope>\n" +
" </q:org>";

checkQuery(query, expected);
}


private void assertXml(QueryType queryType, String expected) throws SchemaException {
MapXNode mapXNode = queryType.getFilter().getFilterClauseXNode();
String realWrapped = getPrismContext().serializeXNodeToString(new RootXNode(new QName("query"), mapXNode), PrismContext.LANG_XML);

// primitive but effective method
int start = realWrapped.indexOf('>')+1;
int end = realWrapped.lastIndexOf('<');
String real = realWrapped.substring(start, end);

String expNorm = StringUtils.normalizeSpace(expected);
String realNorm = StringUtils.normalizeSpace(real);
if (!expNorm.equals(realNorm)) {
String m = "Serialized query is not correct. Expected:\n" + expected + "\nActual:\n" + real + "\n\nNormalized versions:\n\n" +
"Expected: " + expNorm + "\nActual: " + realNorm + "\n";
LOGGER.error("{}", m);
throw new AssertionError(m);
}
}
}

0 comments on commit a9cd540

Please sign in to comment.