use of com.evolveum.midpoint.repo.sql.query2.resolution.DataSearchResult in project midpoint by Evolveum.
the class JpaAnyContainerDefinition method nextLinkDefinition.
@Override
public DataSearchResult nextLinkDefinition(ItemPath path, ItemDefinition itemDefinition, PrismContext prismContext) throws QueryException {
if (ItemPath.asSingleName(path) == null) {
throw new QueryException("Couldn't resolve paths other than those in the form of single name in extension/attributes container: " + path);
}
if (itemDefinition == null) {
throw new QueryException("Couldn't resolve dynamically defined item path '" + path + "' without proper definition");
}
CollectionSpecification collSpec = itemDefinition.isSingleValue() ? null : new CollectionSpecification();
// longs, strings, ...
String jpaName;
JpaDataNodeDefinition jpaNodeDefinition;
if (itemDefinition instanceof PrismPropertyDefinition) {
try {
jpaName = RAnyConverter.getAnySetType(itemDefinition, prismContext);
} catch (SchemaException e) {
throw new QueryException(e.getMessage(), e);
}
// TODO
jpaNodeDefinition = new JpaAnyPropertyDefinition(Object.class, null);
} else if (itemDefinition instanceof PrismReferenceDefinition) {
jpaName = "references";
jpaNodeDefinition = new JpaAnyReferenceDefinition(Object.class, RObject.class);
} else {
throw new QueryException("Unsupported 'any' item: " + itemDefinition);
}
JpaLinkDefinition<?> linkDefinition = new JpaAnyItemLinkDefinition(itemDefinition.getName(), jpaName, collSpec, getOwnerType(), jpaNodeDefinition);
return new DataSearchResult<>(linkDefinition, ItemPath.EMPTY_PATH);
}
use of com.evolveum.midpoint.repo.sql.query2.resolution.DataSearchResult in project midpoint by Evolveum.
the class ItemPathResolutionState method nextState.
/**
* Executes transition to next state. Modifies query context by adding joins as necessary.
*
* Precondition: !isFinal()
* Precondition: adequate transition exists
*
* @param itemDefinition Target item definition (used/required only for "any" properties)
* @param singletonOnly Collections are forbidden
* @return destination state - always not null
*/
public ItemPathResolutionState nextState(ItemDefinition itemDefinition, boolean singletonOnly, PrismContext prismContext) throws QueryException {
// This is brutal hack, to be thought again.
if (remainingItemPath.startsWith(ParentPathSegment.class) && hqlDataInstance.getParentItem() != null) {
return new ItemPathResolutionState(remainingItemPath.tail(), hqlDataInstance.getParentItem(), itemPathResolver);
}
DataSearchResult<?> result = hqlDataInstance.getJpaDefinition().nextLinkDefinition(remainingItemPath, itemDefinition, prismContext);
LOGGER.trace("nextLinkDefinition on '{}' returned '{}'", remainingItemPath, result != null ? result.getLinkDefinition() : "(null)");
if (result == null) {
// sorry we failed (however, this should be caught before -> so IllegalStateException)
throw new IllegalStateException("Couldn't find '" + remainingItemPath + "' in " + hqlDataInstance.getJpaDefinition());
}
JpaLinkDefinition linkDefinition = result.getLinkDefinition();
String newHqlPath = hqlDataInstance.getHqlPath();
if (linkDefinition.hasJpaRepresentation()) {
if (singletonOnly && linkDefinition.isMultivalued()) {
// TODO better message + context
throw new QueryException("Collections are not allowable for right-side paths");
}
if (!linkDefinition.isEmbedded() || linkDefinition.isMultivalued()) {
LOGGER.trace("Adding join for '{}' to context", linkDefinition);
newHqlPath = itemPathResolver.addJoin(linkDefinition, hqlDataInstance.getHqlPath());
} else {
newHqlPath += "." + linkDefinition.getJpaName();
}
}
HqlDataInstance<?> parentDataInstance;
if (!remainingItemPath.startsWith(ParentPathSegment.class)) {
// TODO what about other special cases? (@, ...)
parentDataInstance = hqlDataInstance;
} else {
parentDataInstance = null;
}
return new ItemPathResolutionState(result.getRemainder(), new HqlDataInstance<>(newHqlPath, result.getTargetDefinition(), parentDataInstance), itemPathResolver);
}
use of com.evolveum.midpoint.repo.sql.query2.resolution.DataSearchResult in project midpoint by Evolveum.
the class JpaEntityDefinition method nextLinkDefinition.
@Override
public DataSearchResult<?> nextLinkDefinition(ItemPath path, ItemDefinition<?> itemDefinition, PrismContext prismContext) throws QueryException {
if (ItemPath.isNullOrEmpty(path)) {
// doesn't fulfill precondition
return null;
}
ItemPathSegment first = path.first();
if (first instanceof IdItemPathSegment) {
throw new QueryException("ID item path segments are not allowed in query: " + path);
} else if (first instanceof ObjectReferencePathSegment) {
throw new QueryException("'@' path segment cannot be used in the context of an entity " + this);
}
JpaLinkDefinition<?> link = findRawLinkDefinition(path, JpaDataNodeDefinition.class, false);
if (link == null) {
return null;
} else {
link.resolveEntityPointer();
return new DataSearchResult<>(link, path.tail(link.getItemPath().size()));
}
}
use of com.evolveum.midpoint.repo.sql.query2.resolution.DataSearchResult in project midpoint by Evolveum.
the class ItemPathResolver method findProperDataDefinition.
/**
* Finds the proper definition for (possibly abstract) entity.
* Returns the most abstract entity that can be used.
* Checks for conflicts, such as user.locality vs org.locality.
*
* @param path Path to be found (non-empty!)
* @param itemDefinition Definition of target property, required/used only for "any" properties
* @param clazz Kind of definition to be looked for
* @param prismContext
* @return Entity type definition + item definition, or null if nothing was found
*/
public <T extends JpaDataNodeDefinition> ProperDataSearchResult<T> findProperDataDefinition(JpaEntityDefinition baseEntityDefinition, ItemPath path, ItemDefinition itemDefinition, Class<T> clazz, PrismContext prismContext) throws QueryException {
QueryDefinitionRegistry2 registry = QueryDefinitionRegistry2.getInstance();
ProperDataSearchResult<T> candidateResult = null;
for (JpaEntityDefinition entityDefinition : findPossibleBaseEntities(baseEntityDefinition, registry)) {
DataSearchResult<T> result = entityDefinition.findDataNodeDefinition(path, itemDefinition, clazz, prismContext);
if (result != null) {
if (candidateResult == null) {
candidateResult = new ProperDataSearchResult<>(entityDefinition, result);
} else {
// there is no possibility of false alarm.
if (!candidateResult.getEntityDefinition().isAssignableFrom(entityDefinition)) {
throw new QueryException("Unable to determine root entity for " + path + ": found incompatible candidates: " + candidateResult.getEntityDefinition() + " and " + entityDefinition);
}
}
}
}
LOGGER.trace("findProperDataDefinition: base='{}', path='{}', def='{}', class={} -- returning '{}'", baseEntityDefinition, path, itemDefinition, clazz.getSimpleName(), candidateResult);
return candidateResult;
}
Aggregations