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()); } }