From b472e2062157306863cc3586d00cefdedb9ea836 Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Tue, 11 Mar 2014 16:16:16 +0100 Subject: [PATCH] More work on query ... but still in progress --- .../evolveum/midpoint/prism/PrismContext.java | 2 +- .../prism/parser/PrismBeanConverter.java | 67 ++++----- .../midpoint/prism/parser/QueryConvertor.java | 43 +++--- .../prism/parser/XNodeSerializer.java | 21 ++- .../midpoint/prism/query/EqualsFilter.java | 5 +- .../midpoint/prism/query/ObjectFilter.java | 37 +---- .../prism/query/PropertyValueFilter.java | 68 ++++++--- .../prism/query/QueryJaxbConvertor.java | 22 +-- .../midpoint/prism/query/RefFilter.java | 15 +- .../midpoint/prism/query/ValueFilter.java | 23 +-- .../midpoint/prism/util/PrismAsserts.java | 21 +++ .../midpoint/prism/xnode/ListXNode.java | 9 ++ .../midpoint/prism/xnode/MapXNode.java | 26 ++++ .../midpoint/prism/xnode/PrimitiveXNode.java | 6 + .../midpoint/prism/xnode/RootXNode.java | 9 ++ .../midpoint/prism/xnode/SchemaXNode.java | 6 + .../evolveum/midpoint/prism/xnode/XNode.java | 6 +- .../ns/_public/query_2/SearchFilterType.java | 137 ++++++++++++++---- .../main/resources/xml/ns/public/query-2.xsd | 31 +--- .../main/resources/xml/ns/public/types-2.xsd | 2 +- .../prism/query/TestQueryConvertors.java | 2 +- .../midpoint/schema/TestParseResource.java | 32 +++- .../midpoint/schema/TestQueryConvertor.java | 2 +- 23 files changed, 371 insertions(+), 221 deletions(-) diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContext.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContext.java index 3de653ad4a4..7fd008b30f7 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContext.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContext.java @@ -92,7 +92,7 @@ public static PrismContext create(SchemaRegistry schemaRegistry) { schemaRegistry.setPrismContext(prismContext); prismContext.xnodeProcessor = new XNodeProcessor(prismContext); - prismContext.beanConverter = new PrismBeanConverter(schemaRegistry); + prismContext.beanConverter = new PrismBeanConverter(prismContext); prismContext.parserMap = new HashMap(); DomParser parserDom = new DomParser(schemaRegistry); diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/PrismBeanConverter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/PrismBeanConverter.java index d34456becc4..8f351e2cf80 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/PrismBeanConverter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/PrismBeanConverter.java @@ -47,6 +47,7 @@ import org.w3c.dom.Node; import com.evolveum.midpoint.prism.PrismConstants; +import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.schema.SchemaRegistry; @@ -69,14 +70,29 @@ public class PrismBeanConverter { public static final String DEFAULT_NAMESPACE_PLACEHOLDER = "##default"; - private SchemaRegistry schemaRegistry; + private PrismContext prismContext; - public PrismBeanConverter(SchemaRegistry schemaRegistry) { - this.schemaRegistry = schemaRegistry; + public PrismBeanConverter(PrismContext prismContext) { + this.prismContext = prismContext; + } + + public PrismContext getPrismContext() { + return prismContext; + } + + public void setPrismContext(PrismContext prismContext) { + this.prismContext = prismContext; + } + + private SchemaRegistry getSchemaRegistry() { + if (prismContext == null) { + return null; + } + return prismContext.getSchemaRegistry(); } public boolean canConvert(QName typeName) { - return schemaRegistry.determineCompileTimeClass(typeName) != null; + return getSchemaRegistry().determineCompileTimeClass(typeName) != null; } public boolean canConvert(Class clazz) { @@ -85,7 +101,7 @@ public boolean canConvert(Class clazz) { } public T unmarshall(MapXNode xnode, QName typeQName) throws SchemaException { - Class classType = schemaRegistry.determineCompileTimeClass(typeQName); + Class classType = getSchemaRegistry().determineCompileTimeClass(typeQName); return unmarshall(xnode, classType); } @@ -254,7 +270,7 @@ public T unmarshall(MapXNode xnode, Class beanClass) throws SchemaExcepti //check for subclasses??? if (xsubnode.getTypeQName()!= null){ - Class explicitParamType = schemaRegistry.determineCompileTimeClass(xsubnode.getTypeQName()); + Class explicitParamType = getSchemaRegistry().determineCompileTimeClass(xsubnode.getTypeQName()); if (explicitParamType != null && explicitParamType != null){ paramType = explicitParamType; } @@ -318,42 +334,15 @@ private SearchFilterType unmarshalSearchFilterType(MapXNode xmap) throws SchemaE return null; } SearchFilterType filterType = new SearchFilterType(); - MapXNode xfilter = xmap; - XNode xdesc = xmap.get(SearchFilterType.F_DESCRIPTION); - if (xdesc != null) { - if (xdesc instanceof PrimitiveXNode) { - String desc = ((PrimitiveXNode)xdesc).getParsedValue(DOMUtil.XSD_STRING); - filterType.setDescription(desc); - } - xfilter = new MapXNode(); - for (Entry entry: xmap.entrySet()) { - if (!QNameUtil.match(entry.getKey(), SearchFilterType.F_DESCRIPTION)) { - xfilter.put(entry.getKey(), entry.getValue()); - } - } - } - filterType.setXFilter(xfilter); + filterType.parseFromXNode(xmap, prismContext); return filterType; } - private XNode marshalSearchFilterType(SearchFilterType value) { + private XNode marshalSearchFilterType(SearchFilterType value) throws SchemaException { if (value == null) { return null; } - MapXNode xfilter = value.getXFilter(); - if (value.getDescription() == null) { - return xfilter; - } - MapXNode xmap = new MapXNode(); - if (xfilter != null) { - for (Entry entry: xfilter.entrySet()) { - if (!QNameUtil.match(entry.getKey(), SearchFilterType.F_DESCRIPTION)) { - xmap.put(entry.getKey(), entry.getValue()); - } - } - } - xmap.put(SearchFilterType.F_DESCRIPTION, new PrimitiveXNode(value.getDescription())); - return xmap; + return value.serializeToXNode(prismContext); } @@ -595,7 +584,7 @@ private List getPropOrder(Class beanClass) { public T unmarshallPrimitive(PrimitiveXNode xprim, QName typeQName) throws SchemaException { - Class classType = schemaRegistry.determineCompileTimeClass(typeQName); + Class classType = getSchemaRegistry().determineCompileTimeClass(typeQName); return unmarshallPrimitive(xprim, classType); } @@ -697,7 +686,7 @@ private T postConvertUnmarshall(Object parsedPrimValue) { } } - public XNode marshall(T bean) { + public XNode marshall(T bean) throws SchemaException { if (bean == null) { return null; } @@ -858,7 +847,7 @@ private String determineNamespace(Class beanClass) { return namespace; } - private XNode marshallValue(T value, QName fieldTypeName, boolean isAttribute) { + private XNode marshallValue(T value, QName fieldTypeName, boolean isAttribute) throws SchemaException { if (value == null) { return null; } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/QueryConvertor.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/QueryConvertor.java index e062e9f8d18..6652ba4d1e0 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/QueryConvertor.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/QueryConvertor.java @@ -90,8 +90,6 @@ public class QueryConvertor { private static final QName KEY_FILTER_EQUALS_PATH = new QName(NS_QUERY, "path"); private static final QName KEY_FILTER_EQUALS_MATCHING = new QName(NS_QUERY, "matching"); private static final QName KEY_FILTER_EQUALS_VALUE = new QName(NS_QUERY, "value"); - private static final QName KEY_FILTER_EQUALS_EXPRESSION = new QName(NS_QUERY, "expression"); - private static final QName KEY_FILTER_EQUALS_VALUE_EXPRESSION = new QName(NS_QUERY, "valueExpression"); // deprecated 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"); @@ -279,9 +277,13 @@ private static EqualsFilter expressionEntry = xmap.getSingleEntryThatDoesNotMatch( + KEY_FILTER_EQUALS_VALUE, KEY_FILTER_EQUALS_MATCHING, KEY_FILTER_EQUALS_PATH); + if (expressionEntry != null) { + expressionXnode = new MapXNode(); + expressionXnode.put(expressionEntry.getKey(), expressionEntry.getValue()); } return EqualsFilter.createEqual(itemPath, (PrismPropertyDefinition) itemDefinition, matchingRule, expressionXnode); @@ -326,10 +328,7 @@ private static RefFilter parseRefFilter(XNode xnode, P throw new IllegalStateException("No values to search specified for item " + itemName); } - XNode expressionXnode = xmap.get(KEY_FILTER_EQUALS_EXPRESSION); - if (expressionXnode == null) { - expressionXnode = xmap.get(KEY_FILTER_EQUALS_VALUE_EXPRESSION); - } + MapXNode expressionXnode = null; return RefFilter.createReferenceEqual(itemPath, ref, expressionXnode); } @@ -543,7 +542,7 @@ private static MapXNode serializeEqualsFilter(EqualsFilter filter, XNodeS return map; } - private static MapXNode serializeValueFilter(PropertyValueFilter filter, XNodeSerializer xnodeSerializer) throws SchemaException{ + private static MapXNode serializeValueFilter(PropertyValueFilter filter, XNodeSerializer xnodeSerializer) throws SchemaException { MapXNode map = new MapXNode(); serializeMatchingRule(filter, map); @@ -551,18 +550,26 @@ private static MapXNode serializeValueFilter(PropertyValu ListXNode valuesNode = new ListXNode(); - for (T val : filter.getValues()) { - if (val.getParent() == null) { - val.setParent(filter); + List values = filter.getValues(); + if (values != null) { + for (T val : values) { + if (val.getParent() == null) { + val.setParent(filter); + } + XNode valNode = null; + + valNode = xnodeSerializer.serializeItemValue(val, filter.getDefinition()); + + valuesNode.add(valNode); } - XNode valNode = null; - - valNode = xnodeSerializer.serializeItemValue(val, filter.getDefinition()); - valuesNode.add(valNode); + map.put(KEY_FILTER_EQUALS_VALUE, valuesNode); } - map.put(KEY_FILTER_EQUALS_VALUE, valuesNode); + MapXNode xexpression = filter.getExpression(); + if (xexpression != null) { + map.merge(xexpression); + } return map; } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/XNodeSerializer.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/XNodeSerializer.java index 2e21751c526..8e65f515a7c 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/XNodeSerializer.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/XNodeSerializer.java @@ -64,6 +64,7 @@ import com.evolveum.midpoint.prism.xnode.XNode; import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.exception.SystemException; import com.evolveum.prism.xml.ns._public.types_2.EncryptedDataType; import com.evolveum.prism.xml.ns._public.types_2.ItemPathType; import com.evolveum.prism.xml.ns._public.types_2.PolyStringType; @@ -201,6 +202,24 @@ public XNode serializeItemValue(V itemValue, ItemDefiniti if (definition == null){ return serializePropertyRawValue((PrismPropertyValue) itemValue); } + if (beanConverter.getPrismContext() == null) { + // HACK. Ugly hack. We need to make sure that the bean converter has a prism context. + // If it does not then it cannot serialize any values and the subsequent calls may fail. + // The bean converter usually has a context. The context may be missing if it was initialized + // inside one of the JAXB getters/setters. + // We need to get rid of JAXB entirelly to get rid of hacks like this + PrismContext context = null; + if (definition != null) { + context = definition.getPrismContext(); + } + if (context == null && itemValue.getParent() != null) { + context = itemValue.getParent().getPrismContext(); + } + if (context == null) { + throw new SystemException("Cannot determine prism context when serializing "+itemValue); + } + beanConverter.setPrismContext(context); + } if (itemValue instanceof PrismReferenceValue) { xnode = serializeReferenceValue((PrismReferenceValue)itemValue, (PrismReferenceDefinition) definition); } else if (itemValue instanceof PrismPropertyValue) { @@ -293,7 +312,7 @@ private XNode serializePolyString(PolyString realValue) { return xprim; } - private MapXNode serializeProtectedDataType(ProtectedDataType protectedType) { + private MapXNode serializeProtectedDataType(ProtectedDataType protectedType) throws SchemaException { MapXNode xmap = new MapXNode(); if (protectedType.getEncryptedDataType() != null) { EncryptedDataType encryptedDataType = protectedType.getEncryptedDataType(); diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/EqualsFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/EqualsFilter.java index 0bf121a7d1c..3d08e46343a 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/EqualsFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/EqualsFilter.java @@ -49,6 +49,7 @@ import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.util.PrismUtil; +import com.evolveum.midpoint.prism.xnode.MapXNode; import com.evolveum.midpoint.prism.xnode.XNode; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.exception.SchemaException; @@ -70,11 +71,11 @@ private EqualsFilter(ItemPath parentPath, PrismPropertyDefinition definition, QN super(parentPath, definition, matchingRule); } - EqualsFilter(ItemPath parentPath, PrismPropertyDefinition definition, QName matchingRule, XNode expression) { + EqualsFilter(ItemPath parentPath, PrismPropertyDefinition definition, QName matchingRule, MapXNode expression) { super(parentPath, definition, matchingRule, expression); } - public static EqualsFilter createEqual(ItemPath path, PrismPropertyDefinition definition, QName matchingRule, XNode expression){ + public static EqualsFilter createEqual(ItemPath path, PrismPropertyDefinition definition, QName matchingRule, MapXNode expression){ Validate.notNull(path, "Path must not be null"); // Do not check definition. We may want queries for which the definition is supplied later. return new EqualsFilter(path, definition, matchingRule, expression); diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectFilter.java index 59d063cf675..0605953636a 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2013 Evolveum + * Copyright (c) 2010-2014 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,48 +30,21 @@ -public abstract class ObjectFilter implements DebugDumpable, Serializable{ - -// private ItemPath fullPath; - private XNode expression; - - ObjectFilter(XNode expression) { - this.expression = expression; - } +public abstract class ObjectFilter implements DebugDumpable, Serializable { ObjectFilter() { + // Nothing to do } - - public XNode getExpression() { - return expression; - } - - public void setExpression(XNode expression) { - this.expression = expression; - } - + public abstract ObjectFilter clone(); public abstract boolean match(PrismObject object, MatchingRuleRegistry matchingRuleRegistry); protected void cloneValues(ObjectFilter clone) { - clone.expression = this.expression; } public void accept(Visitor visitor) { visitor.visit(this); } - -// public ItemPath getFullPath() { -// return fullPath; -// } -// -// public ItemPath getParentPath(){ -// if (fullPath == null){ -// return null; -// } -// -// return fullPath.allExceptLast(); -// } - + } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/PropertyValueFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/PropertyValueFilter.java index b85005f6d7a..0de6fdfd79c 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/PropertyValueFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/PropertyValueFilter.java @@ -44,17 +44,19 @@ import com.evolveum.midpoint.prism.match.MatchingRuleRegistry; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.util.PrismUtil; +import com.evolveum.midpoint.prism.xnode.MapXNode; import com.evolveum.midpoint.prism.xnode.XNode; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.prism.xml.ns._public.types_2.PolyStringType; -public abstract class PropertyValueFilter extends ValueFilter implements Itemable{ +public abstract class PropertyValueFilter extends ValueFilter implements Itemable { + private MapXNode expression; private List values; - PropertyValueFilter(){ - + PropertyValueFilter() { + super(); } PropertyValueFilter(ItemPath path, ItemDefinition definition, QName matchingRule, List values) { @@ -72,16 +74,19 @@ public abstract class PropertyValueFilter extends ValueFil this.values = null; } - PropertyValueFilter(ItemPath path, ItemDefinition definition, XNode expression) { - super(path, definition, expression); + PropertyValueFilter(ItemPath path, ItemDefinition definition, MapXNode expression) { + super(path, definition); + this.expression = expression; } - PropertyValueFilter(ItemPath path, ItemDefinition definition, XNode expression, List values) { - super(path, definition, expression); + PropertyValueFilter(ItemPath path, ItemDefinition definition, MapXNode expression, List values) { + super(path, definition); this.values = values; + this.expression = expression; } - PropertyValueFilter(ItemPath path, ItemDefinition definition, QName matchingRule, XNode expression) { - super(path, definition, matchingRule, expression); + PropertyValueFilter(ItemPath path, ItemDefinition definition, QName matchingRule, MapXNode expression) { + super(path, definition, matchingRule); + this.expression = expression; } static List> createPropertyList(PrismPropertyDefinition itemDefinition, PrismPropertyValue values) { @@ -107,7 +112,6 @@ static List> createPropertyList(PrismPropertyDefinitio return pValues; } - static List> createPropertyList(PrismPropertyDefinition itemDefinition, T realValue){ List> pVals = new ArrayList>(); @@ -183,6 +187,14 @@ public Item getFilterItem(){ return filterItem; } + public MapXNode getExpression() { + return expression; + } + + public void setExpression(MapXNode expression) { + this.expression = expression; + } + @Override public boolean match(PrismObject object, MatchingRuleRegistry matchingRuleRegistry){ // if (getObjectItem(object) == null && getValues() == null) { @@ -234,26 +246,34 @@ public String debugDump(int indent, StringBuilder sb){ sb.append("null"); } - sb.append("\n"); - DebugUtil.indentDebugDump(sb, indent+1); - sb.append("VALUE:"); - if (getValues() != null) { + List values = getValues(); + if (values != null) { + sb.append("\n"); + DebugUtil.indentDebugDump(sb, indent+1); + sb.append("VALUE:"); sb.append("\n"); for (PrismValue val : getValues()) { sb.append(DebugUtil.debugDump(val, indent + 2)); } - } else { - sb.append(" null"); } - - sb.append("\n"); - DebugUtil.indentDebugDump(sb, indent+1); - sb.append("MATCHING: "); - if (getMatchingRule() != null) { - sb.append(getMatchingRule()); - } else { - sb.append("default"); + + XNode expression = getExpression(); + if (expression != null) { + sb.append("\n"); + DebugUtil.indentDebugDump(sb, indent+1); + sb.append("EXPRESSION:"); + sb.append("\n"); + sb.append(DebugUtil.debugDump(expression, indent + 2)); + } + + QName matchingRule = getMatchingRule(); + if (matchingRule != null) { + sb.append("\n"); + DebugUtil.indentDebugDump(sb, indent+1); + sb.append("MATCHING: "); + sb.append(matchingRule); } + return sb.toString(); } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/QueryJaxbConvertor.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/QueryJaxbConvertor.java index 450716448ad..610254a30d3 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/QueryJaxbConvertor.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/QueryJaxbConvertor.java @@ -169,24 +169,16 @@ public static ObjectFilter createObjectFilter(Class cl public static QueryType createQueryType(ObjectQuery query, PrismContext prismContext) throws SchemaException{ ObjectFilter filter = query.getFilter(); - try{ - QueryType queryType = new QueryType(); - if (filter != null){ - MapXNode filterXnode = QueryConvertor.serializeFilter(filter, prismContext); - SearchFilterType filterType = new SearchFilterType(); - filterType.setXFilter(filterXnode); - queryType.setFilter(filterType); -// Element filterElement = prismContext.getParserDom().serializeToElement(filterXnode, QueryConvertor.FILTER_ELEMENT_NAME); -// queryType.setFilter(filterElement); - } - - + QueryType queryType = new QueryType(); + if (filter != null){ + SearchFilterType filterType = new SearchFilterType(); + filterType.setSearchFilter(filter); + queryType.setFilter(filterType); + } + queryType.setPaging(PagingConvertor.createPagingType(query.getPaging())); queryType.setCondition(query.getCondition()); return queryType; - } catch (SchemaException ex){ - throw new SchemaException("Failed to convert query. Reason: " + ex.getMessage(), ex); - } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/RefFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/RefFilter.java index 3d3197844e5..cb2c34ebb90 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/RefFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/RefFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2013 Evolveum + * Copyright (c) 2010-2014 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,22 +36,19 @@ import com.evolveum.midpoint.prism.PrismReferenceValue; import com.evolveum.midpoint.prism.match.MatchingRuleRegistry; import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.prism.xnode.MapXNode; import com.evolveum.midpoint.prism.xnode.XNode; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.exception.SchemaException; public class RefFilter extends PropertyValueFilter{ - - /** - * - */ private static final long serialVersionUID = 1L; - RefFilter(ItemPath path, PrismReferenceDefinition definition, XNode expression, List values) { + RefFilter(ItemPath path, PrismReferenceDefinition definition, MapXNode expression, List values) { super(path, definition, expression, values); } - RefFilter(ItemPath path, PrismReferenceDefinition definition, XNode expression) { + RefFilter(ItemPath path, PrismReferenceDefinition definition, MapXNode expression) { super(path, definition, expression); } @@ -67,11 +64,11 @@ public static RefFilter createReferenceEqual(ItemPath path, PrismReferenceDefini return new RefFilter(path, definition, null, Arrays.asList(values)); } - public static RefFilter createReferenceEqual(ItemPath path, PrismReference item, XNode expression){ + public static RefFilter createReferenceEqual(ItemPath path, PrismReference item, MapXNode expression){ return new RefFilter(path, item.getDefinition(), expression, item.getValues()); } - public static RefFilter createReferenceEqual(ItemPath path, PrismReferenceDefinition definition, XNode expression){ + public static RefFilter createReferenceEqual(ItemPath path, PrismReferenceDefinition definition, MapXNode expression){ return new RefFilter(path, definition, expression); } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ValueFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ValueFilter.java index 9cb52f5df12..213cdeff222 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ValueFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ValueFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2013 Evolveum + * Copyright (c) 2010-2014 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,17 +39,13 @@ import com.evolveum.midpoint.util.exception.SchemaException; public abstract class ValueFilter extends ObjectFilter { - - /** - * - */ private static final long serialVersionUID = 1L; private ItemPath fullPath; private ItemDefinition definition; private QName matchingRule; public ValueFilter() { - // TODO Auto-generated constructor stub + super(); } public ValueFilter(ItemPath parentPath, ItemDefinition definition){ @@ -62,20 +58,7 @@ public ValueFilter(ItemPath parentPath, ItemDefinition definition, QName matchin this.definition = definition; this.matchingRule = matchingRule; } - - public ValueFilter(ItemPath parentPath, ItemDefinition definition, QName matchingRule, XNode expression){ - super(expression); - this.fullPath = parentPath; - this.definition = definition; - this.matchingRule = matchingRule; - } - - public ValueFilter(ItemPath parentPath, ItemDefinition definition, XNode expression){ - super(expression); - this.fullPath = parentPath; - this.definition = definition; - } - + public ItemDefinition getDefinition() { return definition; } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/util/PrismAsserts.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/util/PrismAsserts.java index 6f5591511a5..8a92118375a 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/util/PrismAsserts.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/util/PrismAsserts.java @@ -68,6 +68,7 @@ import com.evolveum.midpoint.prism.xml.XmlTypeConverter; import com.evolveum.midpoint.prism.xnode.ListXNode; import com.evolveum.midpoint.prism.xnode.MapXNode; +import com.evolveum.midpoint.prism.xnode.PrimitiveXNode; import com.evolveum.midpoint.prism.xnode.XNode; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.MiscUtil; @@ -792,6 +793,18 @@ public static void assertSubnode(MapXNode xmap, QName key, Class expectedClass) assert expectedClass.isAssignableFrom(xsubnode.getClass()) : "Wrong class of subnode "+key+" in "+xmap+"; expected "+expectedClass+", got "+xsubnode.getClass(); } + public static void assertAllParsedNodes(XNode xnode) { + Visitor visitor = new Visitor() { + @Override + public void visit(Visitable visitable) { + if ((visitable instanceof PrimitiveXNode)) { + assert ((PrimitiveXNode)visitable).isParsed() : "Xnode "+visitable+" is not parsed"; + } + } + }; + xnode.accept(visitor); + } + // Query asserts public static void assertOrFilter(ObjectFilter filter, int conditions) { @@ -889,4 +902,12 @@ public static void assertEqualsCollectionUnordered(String message, Collectio "; was "+actualCollection; } + public static void assertAssignableFrom(Class expected, Class actual) { + assert expected.isAssignableFrom(actual) : "Expected "+expected+" but got "+actual; + } + + public static void assertAssignableFrom(Class expected, Object actualObject) { + assert expected.isAssignableFrom(actualObject.getClass()) : "Expected "+expected+" but got "+actualObject.getClass(); + } + } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/ListXNode.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/ListXNode.java index 140229515dd..27230f607c2 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/ListXNode.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/ListXNode.java @@ -21,6 +21,7 @@ import java.util.List; import java.util.ListIterator; +import com.evolveum.midpoint.prism.Visitor; import com.evolveum.midpoint.util.DebugUtil; public class ListXNode extends XNode implements List { @@ -141,6 +142,14 @@ public ListIterator listIterator(int index) { public List subList(int fromIndex, int toIndex) { return subnodes.subList(fromIndex, toIndex); } + + @Override + public void accept(Visitor visitor) { + visitor.visit(this); + for (XNode subnode: subnodes) { + subnode.accept(visitor); + } + } @Override public String debugDump(int indent) { diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/MapXNode.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/MapXNode.java index 373c3a1fd9c..c36c486e079 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/MapXNode.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/MapXNode.java @@ -27,6 +27,7 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.prism.Visitor; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.MiscUtil; import com.evolveum.midpoint.util.PrettyPrinter; @@ -121,6 +122,23 @@ public java.util.Map.Entry getSingleSubEntry(String errorContext) return subnodes.get(0); } + + public Entry getSingleEntryThatDoesNotMatch(QName... excludedKeys) throws SchemaException { + Entry found = null; + OUTER: for (Entry subentry: subnodes) { + for (QName excludedKey: excludedKeys) { + if (QNameUtil.match(subentry.getKey(), excludedKey)) { + continue OUTER; + } + } + if (found != null) { + throw new SchemaException("More than one extension subnode found under "+this+": "+found.getKey()+" and "+subentry.getKey()); + } else { + found = subentry; + } + } + return found; + } public Set> entrySet() { Set> entries = new Set>() { @@ -230,6 +248,14 @@ public void merge(MapXNode other) { } } + @Override + public void accept(Visitor visitor) { + visitor.visit(this); + for(Entry subentry: subnodes) { + subentry.value.accept(visitor); + } + } + public boolean equals(Object o) { if (!(o instanceof MapXNode)){ return false; diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/PrimitiveXNode.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/PrimitiveXNode.java index 71101dd0c58..86e1abd7629 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/PrimitiveXNode.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/PrimitiveXNode.java @@ -20,6 +20,7 @@ import org.apache.commons.lang.StringUtils; import com.evolveum.midpoint.prism.PrismPropertyDefinition; +import com.evolveum.midpoint.prism.Visitor; import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; import com.evolveum.midpoint.util.DebugUtil; @@ -125,6 +126,11 @@ public String getFormattedValue() { return XmlTypeConverter.toXmlTextContent(value, null); } + @Override + public void accept(Visitor visitor) { + visitor.visit(this); + } + @Override public String debugDump(int indent) { StringBuilder sb = new StringBuilder(); diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/RootXNode.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/RootXNode.java index e291db663d6..016878d6855 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/RootXNode.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/RootXNode.java @@ -21,6 +21,7 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.prism.Visitor; import com.evolveum.midpoint.util.DebugUtil; public class RootXNode extends XNode { @@ -58,6 +59,14 @@ public boolean isEmpty() { return (subnode == null); } + @Override + public void accept(Visitor visitor) { + visitor.visit(this); + if (subnode != null) { + subnode.accept(visitor); + } + } + @Override public String debugDump(int indent) { StringBuilder sb = new StringBuilder(); diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/SchemaXNode.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/SchemaXNode.java index a8301aa6d3d..858b67a63c4 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/SchemaXNode.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/SchemaXNode.java @@ -17,6 +17,7 @@ import org.w3c.dom.Element; +import com.evolveum.midpoint.prism.Visitor; import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.util.DebugUtil; @@ -40,6 +41,11 @@ public void setSchemaElement(Element schemaElement) { public boolean isEmpty() { return schemaElement == null || DOMUtil.isEmpty(schemaElement); } + + @Override + public void accept(Visitor visitor) { + visitor.visit(this); + } @Override public String debugDump(int indent) { diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/XNode.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/XNode.java index 531ce4f0a69..1684f5e1960 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/XNode.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/XNode.java @@ -23,6 +23,8 @@ import org.apache.commons.lang.StringUtils; import com.evolveum.midpoint.prism.ItemDefinition; +import com.evolveum.midpoint.prism.Visitable; +import com.evolveum.midpoint.prism.Visitor; import com.evolveum.midpoint.util.DebugDumpable; import com.evolveum.midpoint.util.Transformer; @@ -30,7 +32,7 @@ * @author semancik * */ -public abstract class XNode implements DebugDumpable { +public abstract class XNode implements DebugDumpable, Visitable { public static final QName KEY_OID = new QName(null, "oid"); public static final QName KEY_VERSION = new QName(null, "version"); @@ -121,6 +123,8 @@ public void setExplicitTypeDeclaration(boolean explicitTypeDeclaration) { this.explicitTypeDeclaration = explicitTypeDeclaration; } + public abstract void accept(Visitor visitor); + public XNode cloneTransformKeys(Transformer keyTransformer) { return cloneTransformKeys(keyTransformer, this); } diff --git a/infra/prism/src/main/java/com/evolveum/prism/xml/ns/_public/query_2/SearchFilterType.java b/infra/prism/src/main/java/com/evolveum/prism/xml/ns/_public/query_2/SearchFilterType.java index 50ca2d98bf3..b5f913100f4 100644 --- a/infra/prism/src/main/java/com/evolveum/prism/xml/ns/_public/query_2/SearchFilterType.java +++ b/infra/prism/src/main/java/com/evolveum/prism/xml/ns/_public/query_2/SearchFilterType.java @@ -26,6 +26,7 @@ import java.util.Locale; import java.util.TimeZone; import java.util.UUID; +import java.util.Map.Entry; import javax.activation.MimeType; import javax.activation.MimeTypeParseException; @@ -40,13 +41,21 @@ import javax.xml.namespace.QName; import com.evolveum.midpoint.prism.PrismConstants; +import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.parser.DomParser; +import com.evolveum.midpoint.prism.parser.PrismBeanConverter; +import com.evolveum.midpoint.prism.parser.QueryConvertor; +import com.evolveum.midpoint.prism.parser.XNodeSerializer; +import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.util.PrismUtil; import com.evolveum.midpoint.prism.xjc.PrismForJAXBUtil; import com.evolveum.midpoint.prism.xnode.MapXNode; +import com.evolveum.midpoint.prism.xnode.PrimitiveXNode; import com.evolveum.midpoint.prism.xnode.XNode; +import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.util.DebugDumpable; import com.evolveum.midpoint.util.DebugUtil; +import com.evolveum.midpoint.util.QNameUtil; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.xml.DomAwareEqualsStrategy; import com.evolveum.midpoint.util.xml.DomAwareHashCodeStrategy; @@ -74,7 +83,7 @@ public class SearchFilterType implements Serializable, Cloneable, Equals, HashCo @XmlAnyElement protected Element filterClause; @XmlTransient - protected MapXNode xfilter; + protected ObjectFilter searchFilter; public final static QName COMPLEX_TYPE = new QName(PrismConstants.NS_QUERY, "SearchFilterType"); public static final QName F_DESCRIPTION = new QName(PrismConstants.NS_QUERY, "description"); @@ -104,7 +113,7 @@ public SearchFilterType(final SearchFilterType o) { throw new NullPointerException("Cannot create a copy of 'QueryType' from 'null'."); } // CWildcardTypeInfo: org.w3c.dom.Element - this.filterClause = ((o.filterClause == null)?null:((o.getFilterClause() == null)?null:((Element) o.getFilterClause().cloneNode(true)))); + this.filterClause = ((o.filterClause == null)?null:((o.filterClause == null)?null:((Element) o.filterClause.cloneNode(true)))); } public String getDescription() { @@ -124,9 +133,12 @@ public void setDescription(String description) { * */ public Element getFilterClause() { - if (xfilter != null) { - DomParser domParser = PrismUtil.getDomParser(null); + if (searchFilter != null) { try { + PrismBeanConverter beanConverter = new PrismBeanConverter(null); + XNodeSerializer xnodeSerilizer = new XNodeSerializer(beanConverter); + MapXNode xfilter = QueryConvertor.serializeFilter(searchFilter, xnodeSerilizer); + DomParser domParser = PrismUtil.getDomParser(null); return domParser.serializeSingleElementMapToElement(xfilter); } catch (SchemaException e) { throw new RuntimeException(e.getMessage(), e); @@ -136,10 +148,6 @@ public Element getFilterClause() { } } - public MapXNode getXFilter() { - return this.xfilter; - } - /** * Sets the value of the filter property. JAXB method. Only for JAXB compatibility. Do not use directly. * @@ -149,28 +157,101 @@ public MapXNode getXFilter() { * */ public void setFilterClause(Element element) { + // This method CANNOT parse the element to filter yet. The element may not be complete + // at this stage. We must do the on-demand parsing instead if (element == null) { - this.xfilter = null; + this.filterClause = null; + this.searchFilter = null; } else { - DomParser domParser = PrismUtil.getDomParser(null); - try { - this.xfilter = domParser.parseElementAsMap(element); - } catch (SchemaException e) { - throw new RuntimeException(e.getMessage(), e); - } + this.filterClause = element; + this.searchFilter = null; } } - public void setXFilter(XNode xnode) { + public ObjectFilter getSearchFilter() { + try { + return getSearchFilter(null); + } catch (SchemaException e) { + throw new RuntimeException(e.getMessage(), e); + } + } + + public ObjectFilter getSearchFilter(PrismContext prismContext) throws SchemaException { + if (searchFilter != null) { + return searchFilter; + } else if (filterClause == null) { + return null; + } else { + DomParser domParser; + if (prismContext != null) { + domParser = prismContext.getParserDom(); + } else { + domParser = PrismUtil.getDomParser(null); + } + MapXNode xnode = domParser.parseElementAsMap(filterClause); + searchFilter = QueryConvertor.parseFilter(xnode, prismContext); + filterClause = null; + return searchFilter; + } + } + + public void setSearchFilter(ObjectFilter searchFilter) { + this.searchFilter = searchFilter; + filterClause = null; + } + + public void parseFromXNode(XNode xnode, PrismContext prismContext) throws SchemaException { + this.filterClause = null; if (xnode == null || xnode.isEmpty()) { - this.xfilter = null; + this.searchFilter = null; + this.description = null; + } else { + if (!(xnode instanceof MapXNode)) { + throw new SchemaException("Cannot parse filter from "+xnode); + } + MapXNode xmap = (MapXNode)xnode; + MapXNode xfilter = xmap; + XNode xdesc = xmap.get(SearchFilterType.F_DESCRIPTION); + if (xdesc != null) { + if (xdesc instanceof PrimitiveXNode) { + String desc = ((PrimitiveXNode)xdesc).getParsedValue(DOMUtil.XSD_STRING); + setDescription(desc); + } + xfilter = new MapXNode(); + for (Entry entry: xmap.entrySet()) { + if (!QNameUtil.match(entry.getKey(), SearchFilterType.F_DESCRIPTION)) { + xfilter.put(entry.getKey(), entry.getValue()); + } + } + } + this.searchFilter = QueryConvertor.parseFilter(xfilter, prismContext); + } + } + + public MapXNode serializeToXNode(PrismContext prismContext) throws SchemaException { + MapXNode xmap; + if (this.filterClause == null && this.searchFilter == null) { + xmap = null; + } else if (this.filterClause == null) { + xmap = QueryConvertor.serializeFilter(searchFilter, prismContext); + } else { + DomParser domParser; + if (prismContext != null) { + domParser = prismContext.getParserDom(); + } else { + domParser = PrismUtil.getDomParser(null); + } + xmap = domParser.parseElementAsMap(filterClause); + } + if (description == null) { + return xmap; } else { - if (xnode instanceof MapXNode) { - this.xfilter = (MapXNode) xnode; - } else { - throw new IllegalArgumentException("Cannot parse filter from "+xnode); - } + if (xmap == null) { + xmap = new MapXNode(); + } + xmap.put(SearchFilterType.F_DESCRIPTION, new PrimitiveXNode(description)); } + return xmap; } /** @@ -187,7 +268,7 @@ public int hashCode(ObjectLocator locator, HashCodeStrategy strategy) { int currentHashCode = 1; { Element theFilter; - theFilter = this.getFilterClause(); + theFilter = this.filterClause; currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "filter", theFilter), currentHashCode, theFilter); } return currentHashCode; @@ -208,9 +289,9 @@ public boolean equals(ObjectLocator thisLocator, ObjectLocator thatLocator, Obje final SearchFilterType that = ((SearchFilterType) object); { Element lhsFilter; - lhsFilter = this.getFilterClause(); + lhsFilter = this.filterClause; Element rhsFilter; - rhsFilter = that.getFilterClause(); + rhsFilter = that.filterClause; if (!strategy.equals(LocatorUtils.property(thisLocator, "filter", lhsFilter), LocatorUtils.property(thatLocator, "filter", rhsFilter), lhsFilter, rhsFilter)) { return false; } @@ -624,7 +705,7 @@ public SearchFilterType clone() { // CC-XJC Version 2.0 Build 2011-09-16T18:27:24+0000 final SearchFilterType clone = ((SearchFilterType) super.clone()); // CWildcardTypeInfo: org.w3c.dom.Element - clone.filterClause = ((this.filterClause == null)?null:((this.getFilterClause() == null)?null:((Element) this.getFilterClause().cloneNode(true)))); + clone.filterClause = ((this.filterClause == null)?null:((this.filterClause == null)?null:((Element) this.filterClause.cloneNode(true)))); return clone; } } catch (CloneNotSupportedException e) { @@ -651,9 +732,9 @@ public String debugDump(int indent) { sb.append("\n"); DebugUtil.debugDumpWithLabel(sb, "condition", filterClause.toString(), indent + 1); } - if (xfilter != null) { + if (searchFilter != null) { sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "xfilter", (DebugDumpable)xfilter, indent + 1); + DebugUtil.debugDumpWithLabel(sb, "searchFilter", searchFilter, indent + 1); } return sb.toString(); } diff --git a/infra/prism/src/main/resources/xml/ns/public/query-2.xsd b/infra/prism/src/main/resources/xml/ns/public/query-2.xsd index e0608c3f3cf..820ff4c1744 100644 --- a/infra/prism/src/main/resources/xml/ns/public/query-2.xsd +++ b/infra/prism/src/main/resources/xml/ns/public/query-2.xsd @@ -32,7 +32,7 @@ TODO - Version: 2.0 + Version: 2.3-SNAPSHOT Recommended namespace prefix: q @@ -216,24 +216,7 @@ - - - - - - The elements and values of queried properties. - Multi-valued properties are not allowed here. - Use "and" or "or" clauses if needed. - - - - - - - - - - + @@ -313,11 +296,11 @@ and we do not have the time to find out. Therefore it should be OK for now. --> - - - - - + + + + + diff --git a/infra/prism/src/main/resources/xml/ns/public/types-2.xsd b/infra/prism/src/main/resources/xml/ns/public/types-2.xsd index 00d4f005e3f..5947e4c59ea 100644 --- a/infra/prism/src/main/resources/xml/ns/public/types-2.xsd +++ b/infra/prism/src/main/resources/xml/ns/public/types-2.xsd @@ -394,7 +394,7 @@ - + diff --git a/infra/prism/src/test/java/com/evolveum/midpoint/prism/query/TestQueryConvertors.java b/infra/prism/src/test/java/com/evolveum/midpoint/prism/query/TestQueryConvertors.java index eef4162dcd4..0584e497214 100644 --- a/infra/prism/src/test/java/com/evolveum/midpoint/prism/query/TestQueryConvertors.java +++ b/infra/prism/src/test/java/com/evolveum/midpoint/prism/query/TestQueryConvertors.java @@ -139,7 +139,7 @@ public void testFilterUserAndJaxb() throws Exception { System.out.println(convertedQueryType.debugDump()); SearchFilterType convertedFilterType = convertedQueryType.getFilter(); - MapXNode xFilter = convertedFilterType.getXFilter(); + MapXNode xFilter = convertedFilterType.serializeToXNode(getPrismContext()); PrismAsserts.assertSize(xFilter, 1); PrismAsserts.assertSubnode(xFilter, AndFilter.ELEMENT_NAME, MapXNode.class); MapXNode xandmap = (MapXNode) xFilter.get(AndFilter.ELEMENT_NAME); diff --git a/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestParseResource.java b/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestParseResource.java index 93c1e934971..daaee36c929 100644 --- a/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestParseResource.java +++ b/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestParseResource.java @@ -24,11 +24,13 @@ import com.evolveum.midpoint.prism.dom.PrismDomProcessor; import com.evolveum.midpoint.prism.parser.DomParser; import com.evolveum.midpoint.prism.parser.XNodeProcessor; +import com.evolveum.midpoint.prism.query.EqualsFilter; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.util.PrismAsserts; import com.evolveum.midpoint.prism.util.JaxbTestUtil; import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.prism.xnode.RootXNode; +import com.evolveum.midpoint.prism.xnode.XNode; import com.evolveum.midpoint.schema.constants.MidPointConstants; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.processor.ResourceSchema; @@ -39,10 +41,12 @@ import com.evolveum.midpoint.xml.ns._public.common.common_2a.ConnectorConfigurationType; import com.evolveum.midpoint.xml.ns._public.common.common_2a.ConnectorType; import com.evolveum.midpoint.xml.ns._public.common.common_2a.ObjectReferenceType; +import com.evolveum.midpoint.xml.ns._public.common.common_2a.ObjectSynchronizationType; import com.evolveum.midpoint.xml.ns._public.common.common_2a.ObjectType; import com.evolveum.midpoint.xml.ns._public.common.common_2a.ResourceObjectTypeDefinitionType; import com.evolveum.midpoint.xml.ns._public.common.common_2a.ResourceType; import com.evolveum.midpoint.xml.ns._public.common.common_2a.SchemaHandlingType; +import com.evolveum.midpoint.xml.ns._public.common.common_2a.SynchronizationType; import com.evolveum.midpoint.xml.ns._public.common.common_2a.XmlSchemaType; import com.evolveum.prism.xml.ns._public.query_2.SearchFilterType; import com.evolveum.prism.xml.ns._public.types_2.PolyStringType; @@ -126,11 +130,10 @@ public void testParseResourceDom() throws Exception { // GIVEN PrismContext prismContext = PrismTestUtil.getPrismContext(); -// Document document = DOMUtil.parseFile(RESOURCE_FILE); -// Element resourceElement = DOMUtil.getFirstChildElement(document); - // WHEN - PrismObject resource = prismContext.parseObject(RESOURCE_FILE); + DomParser parserDom = prismContext.getParserDom(); + XNode xnode = parserDom.parse(RESOURCE_FILE); + PrismObject resource = prismContext.getXnodeProcessor().parseObject(xnode); // THEN System.out.println("Parsed resource:"); @@ -417,6 +420,27 @@ private void assertResourcePrism(PrismObject resource, boolean isS } else { assertNotNull("No schemaHandling property", schemaHandlingProperty); } + + if (!isSimple) { + PrismProperty synchronizationProp = resource.findProperty(ResourceType.F_SYNCHRONIZATION); + SynchronizationType synchronizationType = synchronizationProp.getRealValue(); + ObjectSynchronizationType objectSynchronizationType = synchronizationType.getObjectSynchronization().get(0); + List correlations = objectSynchronizationType.getCorrelation(); + assertEquals("Wrong number of correlation expressions", 1, correlations.size()); + SearchFilterType correlationFilterType = correlations.get(0); + System.out.println("\nCorrelation filter"); + System.out.println(correlationFilterType.debugDump()); + ObjectFilter objectFilter = correlationFilterType.getSearchFilter(); + PrismAsserts.assertAssignableFrom(EqualsFilter.class, objectFilter); + EqualsFilter equalsFilter = (EqualsFilter)objectFilter; + equalsFilter.getFullPath(); + assertNull("Unexpected values in correlation expression", equalsFilter.getValues()); + XNode expression = equalsFilter.getExpression(); + assertNotNull("No expressions in correlation expression", expression); + PrismAsserts.assertAllParsedNodes(expression); + // TODO + } + } private void assertResourceJaxb(ResourceType resourceType, boolean isSimple) { diff --git a/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestQueryConvertor.java b/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestQueryConvertor.java index 85b36250cb7..67a15129719 100644 --- a/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestQueryConvertor.java +++ b/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestQueryConvertor.java @@ -126,7 +126,7 @@ public void testAccountFilter() throws Exception { System.out.println(convertedQueryType.debugDump()); SearchFilterType convertedFilterType = convertedQueryType.getFilter(); - MapXNode xFilter = convertedFilterType.getXFilter(); + MapXNode xFilter = convertedFilterType.serializeToXNode(getPrismContext()); PrismAsserts.assertSize(xFilter, 1); PrismAsserts.assertSubnode(xFilter, AndFilter.ELEMENT_NAME, MapXNode.class); MapXNode xandmap = (MapXNode) xFilter.get(AndFilter.ELEMENT_NAME);