private void addOrdering(InterpretationContext context, ObjectOrdering ordering) throws QueryException { ItemPath orderByPath = ordering.getOrderBy(); // TODO if we'd like to have order-by extension properties, we'd need to provide itemDefinition // for them ProperDataSearchResult<JpaDataNodeDefinition> result = context .getItemPathResolver() .findProperDataDefinition( context.getRootEntityDefinition(), orderByPath, null, JpaDataNodeDefinition.class); if (result == null) { LOGGER.error( "Unknown path '" + orderByPath + "', couldn't find definition for it, " + "list will not be ordered by it."); return; } JpaDataNodeDefinition targetDefinition = result.getLinkDefinition().getTargetDefinition(); if (targetDefinition instanceof JpaAnyContainerDefinition) { throw new QueryException( "Sorting based on extension item or attribute is not supported yet: " + orderByPath); } else if (targetDefinition instanceof JpaReferenceDefinition) { throw new QueryException("Sorting based on reference is not supported: " + orderByPath); } else if (result.getLinkDefinition().isMultivalued()) { throw new QueryException( "Sorting based on multi-valued item is not supported: " + orderByPath); } else if (targetDefinition instanceof JpaEntityDefinition) { throw new QueryException("Sorting based on entity is not supported: " + orderByPath); } else if (!(targetDefinition instanceof JpaPropertyDefinition)) { throw new IllegalStateException("Unknown item definition type: " + result.getClass()); } JpaEntityDefinition baseEntityDefinition = result.getEntityDefinition(); JpaPropertyDefinition orderByDefinition = (JpaPropertyDefinition) targetDefinition; String hqlPropertyPath = context .getItemPathResolver() .resolveItemPath( orderByPath, null, context.getPrimaryEntityAlias(), baseEntityDefinition, true) .getHqlPath(); if (RPolyString.class.equals(orderByDefinition.getJpaClass())) { hqlPropertyPath += ".orig"; } RootHibernateQuery hibernateQuery = context.getHibernateQuery(); if (ordering.getDirection() != null) { switch (ordering.getDirection()) { case ASCENDING: hibernateQuery.addOrdering(hqlPropertyPath, OrderDirection.ASCENDING); break; case DESCENDING: hibernateQuery.addOrdering(hqlPropertyPath, OrderDirection.DESCENDING); break; } } else { hibernateQuery.addOrdering(hqlPropertyPath, OrderDirection.ASCENDING); } }
private <T extends ObjectFilter> Restriction findAndCreateRestrictionInternal( T filter, InterpretationContext context, Restriction parent, ItemPathResolver resolver, JpaEntityDefinition baseEntityDefinition) throws QueryException { // the order of processing restrictions can be important, so we do the selection via handwritten // code if (filter instanceof AndFilter) { return new AndRestriction(context, (AndFilter) filter, baseEntityDefinition, parent); } else if (filter instanceof OrFilter) { return new OrRestriction(context, (OrFilter) filter, baseEntityDefinition, parent); } else if (filter instanceof NotFilter) { return new NotRestriction(context, (NotFilter) filter, baseEntityDefinition, parent); } else if (filter instanceof InOidFilter) { return new InOidRestriction(context, (InOidFilter) filter, baseEntityDefinition, parent); } else if (filter instanceof OrgFilter) { return new OrgRestriction(context, (OrgFilter) filter, baseEntityDefinition, parent); } else if (filter instanceof TypeFilter) { TypeFilter typeFilter = (TypeFilter) filter; JpaEntityDefinition refinedEntityDefinition = resolver.findRestrictedEntityDefinition(baseEntityDefinition, typeFilter.getType()); return new TypeRestriction(context, typeFilter, refinedEntityDefinition, parent); } else if (filter instanceof ExistsFilter) { ExistsFilter existsFilter = (ExistsFilter) filter; ItemPath path = existsFilter.getFullPath(); ItemDefinition definition = existsFilter.getDefinition(); ProperDataSearchResult<JpaEntityDefinition> searchResult = resolver.findProperDataDefinition( baseEntityDefinition, path, definition, JpaEntityDefinition.class); if (searchResult == null) { throw new QueryException( "Path for ExistsFilter (" + path + ") doesn't point to a hibernate entity within " + baseEntityDefinition); } return new ExistsRestriction( context, existsFilter, searchResult.getEntityDefinition(), parent); } else if (filter instanceof RefFilter) { RefFilter refFilter = (RefFilter) filter; ItemPath path = refFilter.getFullPath(); ItemDefinition definition = refFilter.getDefinition(); ProperDataSearchResult<JpaReferenceDefinition> searchResult = resolver.findProperDataDefinition( baseEntityDefinition, path, definition, JpaReferenceDefinition.class); if (searchResult == null) { throw new QueryException( "Path for RefFilter (" + path + ") doesn't point to a reference item within " + baseEntityDefinition); } return new ReferenceRestriction( context, refFilter, searchResult.getEntityDefinition(), parent, searchResult.getLinkDefinition()); } else if (filter instanceof PropertyValueFilter) { PropertyValueFilter valFilter = (PropertyValueFilter) filter; ItemPath path = valFilter.getFullPath(); ItemDefinition definition = valFilter.getDefinition(); ProperDataSearchResult<JpaPropertyDefinition> propDefRes = resolver.findProperDataDefinition( baseEntityDefinition, path, definition, JpaPropertyDefinition.class); if (propDefRes == null) { throw new QueryException( "Couldn't find a proper restriction for a ValueFilter: " + valFilter.debugDump()); } // TODO can't be unified? if (propDefRes.getTargetDefinition() instanceof JpaAnyPropertyDefinition) { return new AnyPropertyRestriction( context, valFilter, propDefRes.getEntityDefinition(), parent, propDefRes.getLinkDefinition()); } else { return new PropertyRestriction( context, valFilter, propDefRes.getEntityDefinition(), parent, propDefRes.getLinkDefinition()); } } else if (filter instanceof NoneFilter || filter instanceof AllFilter || filter instanceof UndefinedFilter) { // these should be filtered out by the client throw new IllegalStateException( "Trivial filters are not supported by QueryInterpreter: " + filter.debugDump()); } else { throw new IllegalStateException("Unknown filter: " + filter.debugDump()); } }