Skip to content

Commit

Permalink
parsing/serializing for type filter (MID-1887)
Browse files Browse the repository at this point in the history
  • Loading branch information
katkav committed May 16, 2014
1 parent 3fdcc62 commit 45edf2d
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 143 deletions.
Expand Up @@ -56,6 +56,7 @@
import com.evolveum.midpoint.prism.query.PropertyValueFilter;
import com.evolveum.midpoint.prism.query.RefFilter;
import com.evolveum.midpoint.prism.query.SubstringFilter;
import com.evolveum.midpoint.prism.query.TypeFilter;
import com.evolveum.midpoint.prism.query.ValueFilter;
import com.evolveum.midpoint.prism.util.PrismUtil;
import com.evolveum.midpoint.prism.xml.XmlTypeConverter;
Expand Down Expand Up @@ -88,6 +89,7 @@ public class QueryConvertor {
public static final QName KEY_FILTER_REF = new QName(NS_QUERY, "ref");
public static final QName KEY_FILTER_SUBSTRING = new QName(NS_QUERY, "substring");
public static final QName KEY_FILTER_ORG = new QName(NS_QUERY, "org");
public static final QName KEY_FILTER_TYPE = new QName(NS_QUERY, "type");

private static final QName KEY_FILTER_EQUAL_PATH = new QName(NS_QUERY, "path");
private static final QName KEY_FILTER_EQUAL_MATCHING = new QName(NS_QUERY, "matching");
Expand All @@ -96,6 +98,9 @@ public class QueryConvertor {
public static final QName KEY_FILTER_SUBSTRING_ANCHOR_START = new QName(NS_QUERY, "anchorStart");
public static final QName KEY_FILTER_SUBSTRING_ANCHOR_END = new QName(NS_QUERY, "anchorEnd");

public static final QName KEY_FILTER_TYPE_TYPE = new QName(NS_QUERY, "type");
public static final QName KEY_FILTER_TYPE_FILTER = new QName(NS_QUERY, "filter");

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");
Expand Down Expand Up @@ -215,6 +220,10 @@ private static <C extends Containerable> ObjectFilter parseFilterContainer(XNode
if (QNameUtil.match(filterQName, KEY_FILTER_ORG)) {
return parseOrgFilter(xsubnode, pcd);
}

if (QNameUtil.match(filterQName, KEY_FILTER_TYPE)) {
return parseTypeFilter(xsubnode, pcd);
}

throw new UnsupportedOperationException("Unsupported query filter " + filterQName);

Expand Down Expand Up @@ -281,11 +290,6 @@ private static <T,C extends Containerable> EqualsFilter<PrismPropertyDefinition<
throw new SchemaException("Cannot convert query, because query does not contain property path.");
}
QName itemName = ItemPath.getName(itemPath.last());
// ItemPath parentPath = itemPath.allExceptLast();
// if (parentPath.isEmpty()){
// parentPath = null;
// }

XNode valueXnode = xmap.get(KEY_FILTER_EQUAL_VALUE);


Expand Down Expand Up @@ -316,6 +320,23 @@ private static <T,C extends Containerable> EqualsFilter<PrismPropertyDefinition<

}

private static TypeFilter parseTypeFilter(XNode xnode, PrismContainerDefinition pcd) throws SchemaException{
MapXNode xmap = toMap(xnode);
QName type = xmap.getParsedPrimitiveValue(KEY_FILTER_TYPE_TYPE, DOMUtil.XSD_QNAME);

XNode subXFilter = xmap.get(KEY_FILTER_TYPE_FILTER);
ObjectFilter subFilter = null;
if (subXFilter != null){
PrismContext prismContext = null;
if (pcd != null && pcd.getPrismContext() != null){
prismContext = pcd.getPrismContext();
}
subFilter = parseFilter(subXFilter, prismContext);
}

return new TypeFilter(type, subFilter);

}


private static <C extends Containerable> RefFilter parseRefFilter(XNode xnode, PrismContainerDefinition<C> pcd) throws SchemaException{
Expand Down Expand Up @@ -552,6 +573,10 @@ public static MapXNode serializeFilter(ObjectFilter filter, XNodeSerializer xnod
if (filter instanceof OrgFilter) {
return serializeOrgFilter((OrgFilter) filter, xnodeSerilizer);
}

if (filter instanceof TypeFilter) {
return serializeTypeFilter((TypeFilter) filter, xnodeSerilizer);
}

throw new UnsupportedOperationException("Unsupported filter type: " + filter);
}
Expand Down Expand Up @@ -629,164 +654,49 @@ private static MapXNode serializeRefFilter(RefFilter filter, XNodeSerializer xno
MapXNode map = new MapXNode();

map.put(KEY_FILTER_REF, serializeValueFilter(filter, xnodeSerializer));

// serializePath(filter, map);
//
// List<PrismReferenceValue> values = (List<PrismReferenceValue>) filter.getValues();
// if (values.size() < 1) {
// throw new SchemaException("No values for search in the ref filter.");
// }
//
// if (values.size() > 1) {
// throw new SchemaException("More than one prism reference value not allowed in the ref filter");
// }
//
//
// PrismReferenceValue val = values.get(0);
//
// XNode refVal = xnodeSerializer.serializeReferenceValue(val, filter.getDefinition());
// map.put(KEY_FILTER_EQUALS_VALUE, refVal);
// if (val.getOid() != null) {
// Element oid = DOMUtil.createElement(doc, PrismConstants.Q_OID);
// oid.setTextContent(String.valueOf(val.getOid()));
// ref.appendChild(oid);
// }
// if (val.getTargetType() != null) {
// Element type = DOMUtil.createElement(doc, PrismConstants.Q_TYPE);
// XPathHolder xtype = new XPathHolder(val.getTargetType());
// type.setTextContent(xtype.getXPath());
// ref.appendChild(type);
// }
// if (val.getRelation() != null) {
// Element relation = DOMUtil.createElement(doc, PrismConstants.Q_RELATION);
// XPathHolder xrelation = new XPathHolder(val.getRelation());
// relation.setTextContent(xrelation.getXPath());
// ref.appendChild(relation);
// }

return map;
}

private static <T> MapXNode serializeSubstringFilter(SubstringFilter<T> filter, XNodeSerializer xnodeSerializer) throws SchemaException{
// Element substring = DOMUtil.createElement(doc, SchemaConstantsGenerated.Q_SUBSTRING);
// Element value = DOMUtil.createElement(doc, SchemaConstantsGenerated.Q_VALUE);
// substring.appendChild(value);
MapXNode map = new MapXNode();
map.put(KEY_FILTER_SUBSTRING, serializeValueFilter(filter, xnodeSerializer));
// serializePath(filter, map);
// Element path = createPathElement(filter, doc);
// substring.appendChild(path);
//
//
// serializeMatchingRule(filter, map);
//
// createMatchingRuleElement(filter, substring, doc);
//
// if (filter.getMatchingRule() != null){
// Element matching = DOMUtil.createElement(doc, SchemaConstantsGenerated.Q_MATCHING);
// matching.setTextContent(filter.getMatchingRule().getLocalPart());
// substring.appendChild(matching);
// }
//
// QName propertyName = filter.getDefinition().getName();
// if (filter.getValues() == null || filter.getValues().isEmpty()){
// substring.appendChild(DOMUtil.createElement(doc, SchemaConstantsGenerated.Q_VALUE));
// }
//
// ListXNode values = new ListXNode();
//
// for (PrismPropertyValue<T> val : filter.getValues()) {
// if (val.getParent() == null) {
// val.setParent(filter);
// }
// XNode valNode = xnodeSerializer.serializePropertyValue(val, filter.getDefinition());
// values.add(valNode);
// Element value = createValueElement(val, propertyName, doc, filter, prismContext);
// substring.appendChild(value);
// }
// map.put(KEY_FILTER_EQUALS_VALUE, values);
//
// Element propValue = DOMUtil.createElement(doc, propertyName);

return map;
}


private static MapXNode serializeTypeFilter(TypeFilter filter, XNodeSerializer xnodeSerializer) throws SchemaException{
MapXNode map = new MapXNode();
map.put(KEY_FILTER_TYPE_TYPE, createPrimitiveXNode(filter.getType(), DOMUtil.XSD_QNAME));

MapXNode subXFilter = null;
if (filter.getFilter() != null){
subXFilter = serializeFilter(filter.getFilter(), xnodeSerializer);
map.put(KEY_FILTER_TYPE_FILTER, subXFilter);
}

MapXNode xtypeFilter= new MapXNode();
xtypeFilter.put(KEY_FILTER_TYPE, map);
return xtypeFilter;

}

private static MapXNode serializeOrgFilter(OrgFilter filter, XNodeSerializer xnodeSerializer) {
// TODO
return null;
// Element org = DOMUtil.createElement(doc, SchemaConstantsGenerated.Q_ORG);
//
// Element orgRef = null;
// if (filter.getOrgRef() != null) {
// orgRef = DOMUtil.createElement(doc, SchemaConstantsGenerated.Q_ORG_REF);
// orgRef.setAttribute("oid", filter.getOrgRef().getOid());
// org.appendChild(orgRef);
// }
//
// Element minDepth = null;
// if (filter.getMinDepth() != null) {
// minDepth = DOMUtil.createElement(doc, SchemaConstantsGenerated.Q_MIN_DEPTH);
// minDepth.setTextContent(XsdTypeMapper.multiplicityToString(filter.getMinDepth()));
// org.appendChild(minDepth);
// }
//
// Element maxDepth = null;
// if (filter.getMaxDepth() != null) {
// maxDepth = DOMUtil.createElement(doc, SchemaConstantsGenerated.Q_MAX_DEPTH);
// maxDepth.setTextContent(XsdTypeMapper.multiplicityToString(filter.getMaxDepth()));
// org.appendChild(maxDepth);
// }
//
// return org;
}

//
//
// private static Element createValueElement(PrismPropertyValue val, QName propertyName, Document doc, PropertyValueFilter filter, PrismContext prismContext) throws SchemaException{
// Element value = DOMUtil.createElement(doc, SchemaConstantsGenerated.Q_VALUE);
// Element element = prismContext.getPrismDomProcessor().serializeValueToDom(val, propertyName, doc);
// if (PolyString.class.equals(filter.getDefinition().getTypeClass()) || PolyStringType.class.equals(filter.getDefinition().getTypeClass())) {
// for (Element e : DOMUtil.listChildElements(element)){
// value.appendChild(e);
// }
// } else{
// value.setTextContent(element.getTextContent());
// }
//// if (XmlTypeConverter.canConvert(val.getClass())){
//// Element propVal = val.asDomElement();
//// value.setTextContent(propVal.getTextContent());
//// } else {
//// value.setTextContent(String.valueOf(((PrismPropertyValue)val).getValue()));
//// }
//// value.setTextContent();
// return value;
//
// }
//

//
private static void serializeMatchingRule(ValueFilter filter, MapXNode map){
if (filter.getMatchingRule() != null){
// PrimitiveXNode<String> matchingNode = new PrimitiveXNode<String>();
// matchingNode.setValue(filter.getMatchingRule().getLocalPart());
// matchingNode.setTypeQName(DOMUtil.XSD_STRING);
PrimitiveXNode<String> matchingNode = createPrimitiveXNode(filter.getMatchingRule().getLocalPart(), DOMUtil.XSD_STRING);
map.put(KEY_FILTER_EQUAL_MATCHING, matchingNode);
}

}

private static void serializePath(ValueFilter filter, MapXNode map) {
// PrimitiveXNode<String> pathNode = new PrimitiveXNode<String>();
// pathNode.setTypeQName(ItemPath.XSD_TYPE);

if (filter.getFullPath() == null){
throw new IllegalStateException("Cannot serialize filter " + filter +" because it does not contain path");
}
// XPathHolder xpath = new XPathHolder(filter.getFullPath());
// String path = xpath.getXPathWithDeclarations();

PrimitiveXNode<ItemPath> pathNode = createPrimitiveXNode(filter.getFullPath(), ItemPath.XSD_TYPE);

map.put(KEY_FILTER_EQUAL_PATH, pathNode);
Expand Down Expand Up @@ -832,12 +742,5 @@ public static void revive (ObjectFilter filter, final PrismContext prismContext)
// }
}

// private static void parseExpression(PropertyValueFilter<?> propValFilter, PrismContext prismContext) throws SchemaException {
// ExpressionWrapper xexpression = propValFilter.getExpression();
// if (xexpression != null) {
// prismContext.getXnodeProcessor().parseGlobalXNodeValues(xexpression);
// }
// }


}
Expand Up @@ -47,6 +47,7 @@
import com.evolveum.midpoint.prism.query.OrFilter;
import com.evolveum.midpoint.prism.query.QueryJaxbConvertor;
import com.evolveum.midpoint.prism.query.RefFilter;
import com.evolveum.midpoint.prism.query.TypeFilter;
import com.evolveum.midpoint.prism.util.PrismAsserts;
import com.evolveum.midpoint.prism.xnode.ListXNode;
import com.evolveum.midpoint.prism.xnode.MapXNode;
Expand Down Expand Up @@ -93,6 +94,7 @@ public class TestQueryConvertor {
"filter-account-by-attributes-and-resource-ref.xml");
private static final File FILTER_OR_COMPOSITE = new File(TEST_DIR, "filter-or-composite.xml");
private static final File FILTER_CONNECTOR_BY_TYPE_FILE = new File(TEST_DIR, "filter-connector-by-type.xml");
private static final File FILTER_BY_TYPE_FILE = new File(TEST_DIR, "filter-by-type.xml");

@BeforeSuite
public void setup() throws SchemaException, SAXException, IOException {
Expand Down Expand Up @@ -251,6 +253,43 @@ public void testConnectorQuery() throws Exception {
}

}

@Test
public void testTypeFilterQuery() throws Exception {
displayTestTitle("testConnectorQuery");
SearchFilterType filterType = PrismTestUtil.parseAtomicValue(FILTER_BY_TYPE_FILE, SearchFilterType.COMPLEX_TYPE);
ObjectQuery query = null;
try {
query = QueryJaxbConvertor.createObjectQuery(ConnectorType.class, filterType, getPrismContext());
displayQuery(query);

assertNotNull(query);
ObjectFilter filter = query.getFilter();
assertTrue("filter is not an instance of type filter", filter instanceof TypeFilter);

TypeFilter typeFilter = (TypeFilter) filter;
assertEquals(typeFilter.getType(), UserType.COMPLEX_TYPE);
assertNotNull("filter in type filter must not be null", typeFilter.getFilter());
PrismAsserts.assertEqualsFilter(typeFilter.getFilter(), UserType.COMPLEX_TYPE, DOMUtil.XSD_QNAME, new ItemPath(UserType.F_NAME));
PrismAsserts.assertEqualsFilterValue((EqualsFilter) typeFilter.getFilter(), "some name identificator");
// PrismAsserts.assertEqualsFilter(query.getFilter(), ConnectorType.F_CONNECTOR_TYPE, DOMUtil.XSD_STRING,
// new ItemPath(ConnectorType.F_CONNECTOR_TYPE));
// PrismAsserts.assertEqualsFilterValue((EqualsFilter) filter, "org.identityconnectors.ldap.LdapConnector");

QueryType convertedQueryType = toQueryType(query);
displayQueryType(convertedQueryType);
} catch (SchemaException ex) {
LOGGER.error("Error while converting query: {}", ex.getMessage(), ex);
throw ex;
} catch (RuntimeException ex) {
LOGGER.error("Error while converting query: {}", ex.getMessage(), ex);
throw ex;
} catch (Exception ex) {
LOGGER.error("Error while converting query: {}", ex.getMessage(), ex);
throw ex;
}

}

private void assertRefFilterValue(RefFilter filter, String oid) {
List<? extends PrismValue> values = filter.getValues();
Expand Down
30 changes: 30 additions & 0 deletions infra/schema/src/test/resources/queryconvertor/filter-by-type.xml
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
~ 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.
-->
<filter
xmlns="http://prism.evolveum.com/xml/ns/public/query-3" xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- <and> -->
<type>
<type>c:UserType</type>
<filter>
<equal>
<path>c:name</path>
<value>some name identificator</value>
</equal>
</filter>
</type>
</filter>

0 comments on commit 45edf2d

Please sign in to comment.