| /* |
| * 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.ode.daohib.bpel.ql; |
| |
| import org.apache.commons.lang.StringUtils; |
| import org.apache.ode.bpel.common.ProcessState; |
| import org.apache.ode.daohib.bpel.hobj.HProcessInstance; |
| import org.apache.ode.ql.Compiler; |
| import org.apache.ode.ql.eval.skel.AbstractConjunction; |
| import org.apache.ode.ql.eval.skel.AbstractDisjunction; |
| import org.apache.ode.ql.eval.skel.AbstractEqualityEvaluator; |
| import org.apache.ode.ql.eval.skel.CommandEvaluator; |
| import org.apache.ode.ql.eval.skel.ConjunctionEvaluator; |
| import org.apache.ode.ql.eval.skel.DisjunctionEvaluator; |
| import org.apache.ode.ql.eval.skel.EqualityEvaluator; |
| import org.apache.ode.ql.eval.skel.GEEvaluator; |
| import org.apache.ode.ql.eval.skel.GreaterEvaluator; |
| import org.apache.ode.ql.eval.skel.INEvaluator; |
| import org.apache.ode.ql.eval.skel.LEEvaluator; |
| import org.apache.ode.ql.eval.skel.LessEvaluator; |
| import org.apache.ode.ql.eval.skel.LikeEvaluator; |
| import org.apache.ode.ql.eval.skel.OrderByEvaluator; |
| import org.apache.ode.ql.tree.Builder; |
| import org.apache.ode.ql.tree.BuilderFactory; |
| import org.apache.ode.ql.tree.nodes.*; |
| import org.apache.ode.utils.ISO8601DateParser; |
| import org.hibernate.Criteria; |
| import org.hibernate.Session; |
| import org.hibernate.criterion.Conjunction; |
| import org.hibernate.criterion.Criterion; |
| import org.hibernate.criterion.Disjunction; |
| import org.hibernate.criterion.Order; |
| import org.hibernate.criterion.Restrictions; |
| |
| import java.text.ParseException; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.Date; |
| import java.util.HashMap; |
| import java.util.LinkedHashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| public class HibernateInstancesQueryCompiler extends Compiler<List, Session> { |
| private static class DBFieldValueEq extends FieldValueEquality { |
| protected final Object fieldValue; |
| |
| /** |
| * @param identifier |
| */ |
| public DBFieldValueEq(String identifier, Object fieldValue) { |
| super(identifier); |
| this.fieldValue = fieldValue; |
| } |
| |
| /** |
| * @see org.apache.ode.ql.eval.skel.CommandEvaluator#evaluate(java.lang.Object) |
| */ |
| public Criterion evaluate(Object paramValue) { |
| return Restrictions.eq(identifier, fieldValue); |
| } |
| } |
| |
| private abstract static class FieldValueEquality extends AbstractEqualityEvaluator<String, Criterion, Object> { |
| |
| /** |
| * @param identifier |
| */ |
| public FieldValueEquality(String identifier) { |
| super(identifier); |
| } |
| |
| } |
| |
| // |
| private final static String INSTANCE_ID_FIELD = "iid"; |
| |
| private final static String PROCESS_ID_FIELD = "pid"; |
| |
| private final static String PROCESS_NAME_FIELD = "name"; |
| |
| private final static String PROCESS_NAMESPACE_FIELD = "namespace"; |
| |
| private final static String INSTANCE_STATUS_FIELD = "status"; |
| |
| private final static String INSTANCE_STARTED_FIELD = "started"; |
| |
| private final static String INSTANCE_LAST_ACTIVE_FIELD = "last-active"; |
| |
| /* |
| * private final static String CORRELATION_NAME_FIELD = "name"; private final static String |
| * CORRELATION_NAMESPACE_FIELD = "namespace"; private final static String CORRELATION_NAMESPACE_FIELD = "namespace"; |
| */ |
| // DB fields |
| private final static String INSTANCE_ID_DB_FIELD = "id"; |
| |
| private final static String PROCESS_ID_DB_FIELD = "process.processId"; |
| |
| private final static String PROCESS_NAME_DB_FIELD = "process.typeName"; |
| |
| private final static String PROCESS_NAMESPACE_DB_FIELD = "process.typeNamespace"; |
| |
| private final static String INSTANCE_STATUS_DB_FIELD = "state"; |
| |
| private final static String PROPERTY_NS_DB_FIELD = "process.typeNamespace"; |
| |
| private final static String PROPERTY_NAME_DB_FIELD = "property.name"; |
| |
| private final static String PROPERTY_VALUE_DB_FIELD = "property.value"; |
| |
| private final static String INSTANCE_STARTED_DB_FIELD = "created"; |
| |
| private final static String INSTANCE_LAST_ACTIVE_DB_FIELD = "lastActiveTime"; |
| |
| // status fields |
| private final static String STATUS_ACTIVE = "active"; |
| |
| private final static String STATUS_SUSPENDED = "suspended"; |
| |
| private final static String STATUS_ERROR = "error"; |
| |
| private final static String STATUS_COMPLETED = "completed"; |
| |
| private final static String STATUS_TERMINATED = "terminated"; |
| |
| private final static String STATUS_FAULTED = "failed"; |
| |
| private final static Map<String, String> nodeIdentifierToDBField = new HashMap<String, String>(20); |
| //Whether property is used in query |
| private boolean propertyInQuery; |
| //Whether ordering by status used |
| private boolean orderByStatus; |
| private boolean orderByStatusDesc; |
| |
| static { |
| nodeIdentifierToDBField.put(INSTANCE_ID_FIELD, INSTANCE_ID_DB_FIELD); |
| nodeIdentifierToDBField.put(INSTANCE_ID_FIELD, INSTANCE_ID_DB_FIELD); |
| nodeIdentifierToDBField.put(PROCESS_ID_FIELD, PROCESS_ID_DB_FIELD); |
| nodeIdentifierToDBField.put(PROCESS_NAME_FIELD, PROCESS_NAME_DB_FIELD); |
| nodeIdentifierToDBField.put(PROCESS_NAMESPACE_FIELD, PROCESS_NAMESPACE_DB_FIELD); |
| nodeIdentifierToDBField.put(INSTANCE_STARTED_FIELD, INSTANCE_STARTED_DB_FIELD); |
| nodeIdentifierToDBField.put(INSTANCE_LAST_ACTIVE_FIELD, INSTANCE_LAST_ACTIVE_DB_FIELD); |
| nodeIdentifierToDBField.put(INSTANCE_STATUS_FIELD, INSTANCE_STATUS_DB_FIELD); |
| } |
| |
| private static String getDBField(String name) { |
| String dbField = nodeIdentifierToDBField.get(name); |
| |
| if (dbField == null) { |
| throw new IllegalArgumentException("Unsupported field " + name); |
| } |
| return dbField; |
| } |
| |
| private void init() { |
| propertyInQuery = false; |
| orderByStatus = false; |
| orderByStatusDesc = false; |
| } |
| |
| @Override |
| public CommandEvaluator<List, Session> compile(final Query node) { |
| init(); |
| |
| final OrderByEvaluator<Collection<Order>, Object> orderEvaluator = (node.getOrder() != null) ? compileOrderBy(node |
| .getOrder()) : null; |
| |
| final CommandEvaluator<Criterion, Object> selectionEvaluator = node.getChilds().size() == 0 ? null |
| : compileEvaluator(node.getChilds().iterator().next()); |
| |
| final boolean joinCorrelationSet = propertyInQuery; |
| final boolean sortByStatus = orderByStatus; |
| final boolean sortByStatusDesc = orderByStatusDesc; |
| final Limit limit = node.getLimit(); |
| |
| return new CommandEvaluator<List, Session>() { |
| public List evaluate(Session session) { |
| Criteria criteria = session.createCriteria(HProcessInstance.class).createAlias("process", "process"); |
| if(joinCorrelationSet) { |
| criteria = criteria.createAlias("correlationSets", "property"); |
| } |
| if(selectionEvaluator!=null) { |
| criteria.add(selectionEvaluator.evaluate(null)); |
| } |
| if (orderEvaluator != null) { |
| Collection<Order> orders = orderEvaluator.evaluate(null); |
| for (Order order : orders) { |
| criteria.addOrder(order); |
| } |
| } |
| // setting limit |
| if (limit != null) { |
| criteria.setMaxResults(limit.getNumber()); |
| } |
| |
| List result = criteria.list(); |
| //check whether ordering by status |
| if(sortByStatus) { |
| Collections.sort(result, sortByStatusDesc?StateComparator.DESC:StateComparator.ASC); |
| } |
| |
| return result; |
| }; |
| }; |
| } |
| |
| protected ConjunctionEvaluator<Criterion, Object> compileConjunction(Collection<CommandEvaluator> childs) { |
| return new AbstractConjunction<Criterion, Object>(childs) { |
| public Criterion evaluate(Object arg) { |
| Conjunction conj = Restrictions.conjunction(); |
| for (CommandEvaluator eval : childs) { |
| conj.add((Criterion) eval.evaluate(null)); |
| } |
| return conj; |
| } |
| }; |
| } |
| |
| protected DisjunctionEvaluator<Criterion, Object> compileDisjunction(Collection<CommandEvaluator> childs) { |
| return new AbstractDisjunction<Criterion, Object>(childs) { |
| public Criterion evaluate(Object arg) { |
| Disjunction conj = Restrictions.disjunction(); |
| for (CommandEvaluator eval : childs) { |
| conj.add((Criterion) eval.evaluate(null)); |
| } |
| return conj; |
| }; |
| }; |
| } |
| |
| protected EqualityEvaluator<String, Criterion, Object> compileEqual(final Equality eq) { |
| if (eq.getIdentifier() instanceof Property) { |
| propertyInQuery = true; |
| final Property property = (Property) eq.getIdentifier(); |
| return new EqualityEvaluator<String, Criterion, Object>() { |
| public Criterion evaluate(Object paramValue) { |
| Conjunction conj = Restrictions.conjunction(); |
| if (!StringUtils.isEmpty(property.getNamespace())) { |
| conj.add(Restrictions.eq(PROPERTY_NS_DB_FIELD, property.getNamespace())); |
| } |
| conj.add(Restrictions.eq(PROPERTY_NAME_DB_FIELD, property.getName())); |
| conj.add(Restrictions.eq(PROPERTY_VALUE_DB_FIELD, eq.getValue().getValue())); |
| |
| return conj; |
| }; |
| |
| public String getIdentifier() { |
| return property.toString(); |
| }; |
| }; |
| } else { |
| final String fieldName = eq.getIdentifier().getName(); |
| final Object value = eq.getValue().getValue(); |
| |
| final String dbField = getDBField(fieldName); |
| |
| if (INSTANCE_STATUS_FIELD.equals(fieldName)) { |
| return new FieldValueEquality(INSTANCE_STATUS_FIELD) { |
| /** |
| * @see org.apache.ode.ql.eval.skel.CommandEvaluator#evaluate(java.lang.Object) |
| */ |
| public Criterion evaluate(Object paramValue) { |
| short noState = 200; // TODO move to constants |
| Disjunction disj = Restrictions.disjunction(); |
| |
| if (STATUS_ACTIVE.equals(paramValue)) { |
| disj.add(Restrictions.eq(dbField, ProcessState.STATE_NEW)); |
| disj.add(Restrictions.eq(dbField, ProcessState.STATE_ACTIVE)); |
| disj.add(Restrictions.eq(dbField, ProcessState.STATE_READY)); |
| } else if (STATUS_SUSPENDED.equals(paramValue)) { |
| disj.add(Restrictions.eq(dbField, ProcessState.STATE_SUSPENDED)); |
| } else if (STATUS_ERROR.equals(value)) { |
| disj.add(Restrictions.eq(dbField, noState)); // Error instance state doesn't exist yet |
| } else if (STATUS_COMPLETED.equals(paramValue)) { |
| disj.add(Restrictions.eq(dbField, ProcessState.STATE_COMPLETED_OK)); |
| } else if (STATUS_TERMINATED.equals(paramValue)) { |
| disj.add(Restrictions.eq(dbField, ProcessState.STATE_TERMINATED)); |
| } else if (STATUS_FAULTED.equals(paramValue)) { |
| disj.add(Restrictions.eq(dbField, ProcessState.STATE_COMPLETED_WITH_FAULT)); |
| } else { |
| disj.add(Restrictions.eq(dbField, noState)); // Non existent state |
| } |
| return disj; |
| } |
| }; |
| } |
| |
| return new DBFieldValueEq(dbField, value); |
| } |
| } |
| |
| public CommandEvaluator compileEvaluator(Object node) { |
| /* |
| * |
| */ |
| if (node instanceof In) { |
| return compileIn((In) node); |
| } else if (node instanceof org.apache.ode.ql.tree.nodes.Conjunction) { |
| return compileConjunction(evaluate((LogicExprNode) node)); |
| } else if (node instanceof org.apache.ode.ql.tree.nodes.Disjunction) { |
| return compileDisjunction(evaluate((LogicExprNode) node)); |
| } else if (node instanceof IdentifierToValueCMP) { |
| return compileIdentifierToValueCMP((IdentifierToValueCMP) node); |
| } |
| throw new IllegalArgumentException("Unsupported node " + node.getClass()); |
| } |
| |
| protected CommandEvaluator<Criterion, Object> compileIdentifierToValueCMP(IdentifierToValueCMP node) { |
| Identifier id = node.getIdentifier(); |
| if (id instanceof Field) { |
| String name = id.getName(); |
| Value value = node.getValue(); |
| if (INSTANCE_ID_FIELD.equals(name)) { |
| value.setValue(Long.valueOf((String) value.getValue())); |
| } else if (INSTANCE_STARTED_FIELD.equals(name) || INSTANCE_LAST_ACTIVE_FIELD.equals(name)) { |
| try { |
| value.setValue(ISO8601DateParser.parse((String) value.getValue())); |
| } catch (ParseException ex) { |
| // TODO |
| throw new RuntimeException(ex); |
| } |
| } |
| } |
| if (node instanceof Equality) { |
| return compileEqual((Equality) node); |
| } else if (node instanceof Less) { |
| return compileLess((Less) node); |
| } else if (node instanceof Greater) { |
| return compileGreater((Greater) node); |
| } else if (node instanceof GE) { |
| return compileGE((GE) node); |
| } else if (node instanceof LE) { |
| return compileLE((LE) node); |
| } else if (node instanceof Like) { |
| return compileLike((Like) node); |
| } else { |
| throw new IllegalArgumentException("Unsupported node " + node.getClass()); |
| } |
| } |
| |
| protected GEEvaluator<String, Criterion, Object> compileGE(final GE ge) { |
| if (ge.getIdentifier() instanceof Property) { |
| propertyInQuery = true; |
| final Property property = (Property) ge.getIdentifier(); |
| return new GEEvaluator<String, Criterion, Object>() { |
| public Criterion evaluate(Object paramValue) { |
| Conjunction conj = Restrictions.conjunction(); |
| if (!StringUtils.isEmpty(property.getNamespace())) { |
| conj.add(Restrictions.ge(PROPERTY_NS_DB_FIELD, property.getNamespace())); |
| } |
| conj.add(Restrictions.ge(PROPERTY_NAME_DB_FIELD, property.getName())); |
| conj.add(Restrictions.ge(PROPERTY_VALUE_DB_FIELD, ge.getValue().getValue())); |
| |
| return conj; |
| }; |
| |
| public String getIdentifier() { |
| return property.toString(); |
| }; |
| }; |
| } else { |
| final String fieldName = ge.getIdentifier().getName(); |
| final Object objValue = ge.getValue().getValue(); |
| |
| if (INSTANCE_STATUS_FIELD.equals(fieldName)) { |
| throw new IllegalArgumentException("Field " + INSTANCE_STATUS_FIELD + " is not supported."); |
| } |
| |
| final String dbField = getDBField(fieldName); |
| |
| return new GEEvaluator<String, Criterion, Object>() { |
| public Criterion evaluate(Object paramValue) { |
| return Restrictions.ge(dbField, objValue); |
| } |
| |
| public String getIdentifier() { |
| return fieldName; |
| } |
| }; |
| } |
| } |
| |
| protected GreaterEvaluator<String, Criterion, Object> compileGreater(final Greater gt) { |
| if (gt.getIdentifier() instanceof Property) { |
| propertyInQuery = true; |
| final Property property = (Property) gt.getIdentifier(); |
| return new GreaterEvaluator<String, Criterion, Object>() { |
| public Criterion evaluate(Object paramValue) { |
| Conjunction conj = Restrictions.conjunction(); |
| if (!StringUtils.isEmpty(property.getNamespace())) { |
| conj.add(Restrictions.gt(PROPERTY_NS_DB_FIELD, property.getNamespace())); |
| } |
| conj.add(Restrictions.gt(PROPERTY_NAME_DB_FIELD, property.getName())); |
| conj.add(Restrictions.gt(PROPERTY_VALUE_DB_FIELD, gt.getValue().getValue())); |
| |
| return conj; |
| }; |
| |
| public String getIdentifier() { |
| return property.toString(); |
| }; |
| }; |
| } else { |
| final String fieldName = gt.getIdentifier().getName(); |
| final Object value = gt.getValue().getValue(); |
| |
| if (INSTANCE_STATUS_FIELD.equals(fieldName)) { |
| throw new IllegalArgumentException("Field " + INSTANCE_STATUS_FIELD + " is not supported."); |
| } |
| |
| final String dbField = getDBField(fieldName); |
| |
| return new GreaterEvaluator<String, Criterion, Object>() { |
| public Criterion evaluate(Object paramValue) { |
| return Restrictions.gt(dbField, value); |
| } |
| |
| public String getIdentifier() { |
| return fieldName; |
| } |
| }; |
| } |
| } |
| |
| protected INEvaluator<String, Criterion, Object> compileIn(final In in) { |
| if (in.getIdentifier() instanceof Property) { |
| propertyInQuery = true; |
| final Property property = (Property) in.getIdentifier(); |
| return new INEvaluator<String, Criterion, Object>() { |
| public Criterion evaluate(Object paramValue) { |
| Disjunction disj = Restrictions.disjunction(); |
| |
| String propertyNS = property.getNamespace(); |
| String propertyName = property.getName(); |
| |
| for (Value value : in.getValues()) { |
| Conjunction conj = Restrictions.conjunction(); |
| if (!StringUtils.isEmpty(property.getNamespace())) { |
| conj.add(Restrictions.gt(PROPERTY_NS_DB_FIELD, propertyNS)); |
| } |
| conj.add(Restrictions.gt(PROPERTY_NAME_DB_FIELD, propertyName)); |
| conj.add(Restrictions.gt(PROPERTY_VALUE_DB_FIELD, value.getValue())); |
| |
| disj.add(conj); |
| } |
| return disj; |
| }; |
| |
| public String getIdentifier() { |
| return property.toString(); |
| }; |
| }; |
| } else { |
| final String fieldName = in.getIdentifier().getName(); |
| |
| if (INSTANCE_STATUS_FIELD.equals(fieldName)) { |
| short noState = 200; // TODO move to constants |
| final Disjunction disj = Restrictions.disjunction(); |
| |
| final Collection values = ValuesHelper.extract((Collection<Value>) in.getValues()); |
| |
| if (values.contains(STATUS_ACTIVE)) { |
| disj.add(Restrictions.eq(INSTANCE_STATUS_DB_FIELD, ProcessState.STATE_NEW)); |
| disj.add(Restrictions.eq(INSTANCE_STATUS_DB_FIELD, ProcessState.STATE_ACTIVE)); |
| disj.add(Restrictions.eq(INSTANCE_STATUS_DB_FIELD, ProcessState.STATE_READY)); |
| } |
| if (values.contains(STATUS_SUSPENDED)) { |
| disj.add(Restrictions.eq(INSTANCE_STATUS_DB_FIELD, ProcessState.STATE_SUSPENDED)); |
| } |
| if (values.contains(STATUS_ERROR)) { |
| disj.add(Restrictions.eq(INSTANCE_STATUS_DB_FIELD, noState)); // Error instance state doesn't exist yet |
| } |
| if (values.contains(STATUS_COMPLETED)) { |
| disj.add(Restrictions.eq(INSTANCE_STATUS_DB_FIELD, ProcessState.STATE_COMPLETED_OK)); |
| } |
| if (values.contains(STATUS_TERMINATED)) { |
| disj.add(Restrictions.eq(INSTANCE_STATUS_DB_FIELD, ProcessState.STATE_TERMINATED)); |
| } |
| if (values.contains(STATUS_FAULTED)) { |
| disj.add(Restrictions.eq(INSTANCE_STATUS_DB_FIELD, ProcessState.STATE_COMPLETED_WITH_FAULT)); |
| } |
| return new INEvaluator<String, Criterion, Object>() { |
| public Criterion evaluate(Object paramValue) { |
| return disj; |
| }; |
| |
| public String getIdentifier() { |
| return INSTANCE_STATUS_DB_FIELD; |
| }; |
| }; |
| } else { |
| final Collection objValues; |
| final Collection<Value> values = in.getValues(); |
| if (INSTANCE_ID_FIELD.equals(fieldName)) { |
| objValues = new ArrayList<Long>(values.size()); |
| for (Value value : values) { |
| objValues.add(Long.valueOf((String) value.getValue())); |
| } |
| } else if (INSTANCE_STARTED_FIELD.equals(fieldName) || INSTANCE_LAST_ACTIVE_FIELD.equals(fieldName)) { |
| objValues = new ArrayList<Date>(values.size()); |
| try { |
| for (Value value : values) { |
| objValues.add(ISO8601DateParser.parse((String) value.getValue())); |
| } |
| } catch (ParseException ex) { |
| // TODO |
| throw new RuntimeException(ex); |
| } |
| } else { |
| objValues = ValuesHelper.extract((Collection<Value>) values); |
| } |
| final String dbField = getDBField(fieldName); |
| return new INEvaluator<String, Criterion, Object>() { |
| /** |
| * @see org.apache.ode.ql.eval.skel.CommandEvaluator#evaluate(java.lang.Object) |
| */ |
| public Criterion evaluate(Object paramValue) { |
| return Restrictions.in(dbField, objValues); |
| } |
| |
| /** |
| * @see org.apache.ode.ql.eval.skel.Identified#getIdentifier() |
| */ |
| public String getIdentifier() { |
| return dbField; |
| } |
| }; |
| } |
| } |
| } |
| |
| protected LEEvaluator<String, Criterion, Object> compileLE(final LE le) { |
| if (le.getIdentifier() instanceof Property) { |
| final Property property = (Property) le.getIdentifier(); |
| return new LEEvaluator<String, Criterion, Object>() { |
| public Criterion evaluate(Object paramValue) { |
| Conjunction conj = Restrictions.conjunction(); |
| if (!StringUtils.isEmpty(property.getNamespace())) { |
| conj.add(Restrictions.le(PROPERTY_NS_DB_FIELD, property.getNamespace())); |
| } |
| conj.add(Restrictions.le(PROPERTY_NAME_DB_FIELD, property.getName())); |
| conj.add(Restrictions.le(PROPERTY_VALUE_DB_FIELD, le.getValue().getValue())); |
| |
| return conj; |
| }; |
| |
| public String getIdentifier() { |
| return property.toString(); |
| }; |
| }; |
| } else { |
| final String fieldName = le.getIdentifier().getName(); |
| final Object value = le.getValue().getValue(); |
| |
| if (INSTANCE_STATUS_FIELD.equals(fieldName)) { |
| throw new IllegalArgumentException("Field " + INSTANCE_STATUS_FIELD + " is not supported."); |
| } |
| |
| final String dbField = getDBField(fieldName); |
| |
| return new LEEvaluator<String, Criterion, Object>() { |
| public Criterion evaluate(Object paramValue) { |
| return Restrictions.le(dbField, value); |
| } |
| |
| public String getIdentifier() { |
| return fieldName; |
| } |
| }; |
| } |
| } |
| |
| protected LessEvaluator<String, Criterion, Object> compileLess(final Less less) { |
| if (less.getIdentifier() instanceof Property) { |
| propertyInQuery = true; |
| final Property property = (Property) less.getIdentifier(); |
| return new LessEvaluator<String, Criterion, Object>() { |
| public Criterion evaluate(Object paramValue) { |
| Conjunction conj = Restrictions.conjunction(); |
| if (!StringUtils.isEmpty(property.getNamespace())) { |
| conj.add(Restrictions.lt(PROPERTY_NS_DB_FIELD, property.getNamespace())); |
| } |
| conj.add(Restrictions.lt(PROPERTY_NAME_DB_FIELD, property.getName())); |
| conj.add(Restrictions.lt(PROPERTY_VALUE_DB_FIELD, less.getValue().getValue())); |
| |
| return conj; |
| }; |
| |
| public String getIdentifier() { |
| return property.toString(); |
| }; |
| }; |
| } else { |
| final String fieldName = less.getIdentifier().getName(); |
| final Object value = less.getValue().getValue(); |
| |
| if (INSTANCE_STATUS_FIELD.equals(fieldName)) { |
| throw new IllegalArgumentException("Field " + INSTANCE_STATUS_FIELD + " is not supported."); |
| } |
| |
| final String dbField = getDBField(fieldName); |
| |
| return new LessEvaluator<String, Criterion, Object>() { |
| public Criterion evaluate(Object paramValue) { |
| return Restrictions.lt(dbField, value); |
| } |
| |
| public String getIdentifier() { |
| return fieldName; |
| } |
| }; |
| } |
| } |
| |
| protected LikeEvaluator<String, Criterion, Object> compileLike(final Like like) { |
| if (like.getIdentifier() instanceof Property) { |
| propertyInQuery = true; |
| final Property property = (Property) like.getIdentifier(); |
| return new LikeEvaluator<String, Criterion, Object>() { |
| public Criterion evaluate(Object paramValue) { |
| Conjunction conj = Restrictions.conjunction(); |
| if (!StringUtils.isEmpty(property.getNamespace())) { |
| conj.add(Restrictions.like(PROPERTY_NS_DB_FIELD, property.getNamespace())); |
| } |
| conj.add(Restrictions.like(PROPERTY_NAME_DB_FIELD, property.getName())); |
| conj.add(Restrictions.like(PROPERTY_VALUE_DB_FIELD, like.getValue().getValue())); |
| |
| return conj; |
| }; |
| |
| public String getIdentifier() { |
| return property.toString(); |
| }; |
| }; |
| } else { |
| final String fieldName = like.getIdentifier().getName(); |
| if (INSTANCE_STATUS_FIELD.equals(fieldName)) { |
| throw new IllegalArgumentException("Field " + INSTANCE_STATUS_FIELD + " is not supported by like operation."); |
| } |
| if (INSTANCE_ID_FIELD.equals(fieldName)) { |
| throw new IllegalArgumentException("Field " + INSTANCE_ID_FIELD + " is not supported by like operation."); |
| } |
| |
| final Object value = like.getValue().getValue(); |
| final String dbField = getDBField(fieldName); |
| |
| return new LikeEvaluator<String, Criterion, Object>() { |
| public Criterion evaluate(Object paramValue) { |
| return Restrictions.like(dbField, value); |
| }; |
| |
| public String getIdentifier() { |
| return dbField; |
| } |
| }; |
| } |
| } |
| |
| protected OrderByEvaluator<Collection<Order>, Object> compileOrderBy(OrderBy orderBy) { |
| final LinkedHashMap<String, Boolean> orders = new LinkedHashMap<String, Boolean>(); |
| |
| for (OrderByElement idOrder : orderBy.getOrders()) { |
| if (!(idOrder.getIdentifier() instanceof Field)) { |
| throw new IllegalArgumentException("Only field identifier supported by order by operator."); |
| } |
| String idName = idOrder.getIdentifier().getName(); |
| if(INSTANCE_STATUS_FIELD.equals(idName)) { |
| if(orderBy.getOrders().size()>1) { |
| //TODO throw appropriate exception |
| throw new RuntimeException("Status field should be used alone in <order by> construction."); |
| } |
| orderByStatus = true; |
| orderByStatusDesc = idOrder.getType()==OrderByType.DESC; |
| return null; |
| } |
| String dbField = getDBField(idName); |
| |
| orders.put(dbField, idOrder.getType() == null || idOrder.getType() == OrderByType.ASC); |
| } |
| |
| return new OrderByEvaluator<Collection<Order>, Object>() { |
| public Collection<Order> evaluate(Object paramValue) { |
| Collection<Order> hibernateOrders = new ArrayList<Order>(orders.size()); |
| for (Map.Entry<String, Boolean> order : orders.entrySet()) { |
| hibernateOrders.add(order.getValue() ? Order.asc(order.getKey()) : Order.desc(order.getKey())); |
| } |
| return hibernateOrders; |
| } |
| }; |
| } |
| |
| protected List<CommandEvaluator> evaluate(LogicExprNode exprNode) { |
| ArrayList<CommandEvaluator> commandsEv = new ArrayList<CommandEvaluator>(exprNode.getChilds().size()); |
| for (LogicNode node : exprNode.getChilds()) { |
| commandsEv.add(compileEvaluator(node)); |
| } |
| return commandsEv; |
| } |
| |
| public static void main(String[] args) { |
| String queryString = "order by last-active desc limit 1000"; |
| Builder<String> builder = BuilderFactory.getInstance().createBuilder(); |
| Node queryNode = builder.build(queryString); |
| HibernateInstancesQueryCompiler compiler = new HibernateInstancesQueryCompiler(); |
| |
| compiler.compile((Query) queryNode); |
| } |
| } |