/*
* Copyright (c) 2010-2015 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.
*/
package com.evolveum.midpoint.prism.query.builder;
import com.evolveum.midpoint.prism.ComplexTypeDefinition;
import com.evolveum.midpoint.prism.Containerable;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.util.exception.SchemaException;
/**
* Here is the language structure:
Query ::= Filter? ('ASC(path)' | 'DESC(path)')*
Filter ::= 'NOT'? SimpleFilter ( ('AND'|'OR') 'NOT'? SimpleFilter )*
SimpleFilter ::= PrimitiveFilter |
'BLOCK' Filter 'END-BLOCK' |
'TYPE(type)' Filter |
'EXISTS(path)' Filter
PrimitiveFilter ::= 'ALL' | 'NONE' | 'UNDEFINED' |
('ITEM(path)' ( ValueComparisonCondition | 'IS-NULL' | ( ItemComparisonCondition 'ITEM(path)') ) ) |
('ID(values)') | ('OWNER-ID(values)')
ValueComparisonCondition ::= 'EQ(value)' | 'GT(value)' | 'GE(value)' | 'LT(value)' | 'LE(value)' | 'STARTSWITH(value)' | 'ENDSWITH(value)' | 'CONTAINS(value)' | 'REF(value)' | 'ORG(value)'
ItemComparisonCondition ::= 'EQ' | 'GT' | 'GE' | 'LT' | 'LE'
*
* It can be visualized e.g. using http://www.bottlecaps.de/rr/ui
*
* Individual keywords ('AND', 'OR', 'BLOCK', ...) are mapped to methods.
* Connections between these keywords are mapped to interfaces.
* It can be viewed as interfaces = states, keywords = transitions. (Or vice versa, but this is more natural.)
* The interfaces have names starting with S_ (for "state").
*
* Interfaces are implemented by classes that aggregate state of the query being created. This is quite hacked for now... to be implemented more seriously.
*
* @author mederly
*/
public class QueryBuilder {
final private Class<? extends Containerable> queryClass;
final private ComplexTypeDefinition containerCTD;
final private PrismContext prismContext;
private QueryBuilder(Class<? extends Containerable> queryClass, PrismContext prismContext) {
this.queryClass = queryClass;
this.prismContext = prismContext;
containerCTD = prismContext.getSchemaRegistry().findComplexTypeDefinitionByCompileTimeClass(queryClass);
if (containerCTD == null) {
throw new IllegalArgumentException("Couldn't find definition for complex type " + queryClass);
}
}
public Class<? extends Containerable> getQueryClass() {
return queryClass;
}
public PrismContext getPrismContext() {
return prismContext;
}
public static S_FilterEntryOrEmpty queryFor(Class<? extends Containerable> queryClass, PrismContext prismContext) {
QueryBuilder builder = new QueryBuilder(queryClass, prismContext);
return R_Filter.create(builder);
}
// ItemDefinition findItemDefinition(ItemPath itemPath) throws SchemaException {
// ItemDefinition itemDefinition = containerCTD.findItemDefinition(itemPath);
// if (itemDefinition == null) {
// throw new SchemaException("Couldn't find definition for '" + itemPath + "' in " + containerCTD);
// }
// return itemDefinition;
// }
}