use of com.evolveum.midpoint.prism.path.ParentPathSegment in project midpoint by Evolveum.
the class ClassDefinitionParser method parseMethod.
private JpaLinkDefinition parseMethod(Method method) {
// non-null if return type is Set<X>, null if it's X
CollectionSpecification collectionSpecification;
// X in return type, which is either X or Set<X>
Type returnedContentType;
if (Set.class.isAssignableFrom(method.getReturnType())) {
// e.g. Set<RObject> or Set<String> or Set<REmbeddedReference<RFocus>>
Type returnType = method.getGenericReturnType();
if (!(returnType instanceof ParameterizedType)) {
throw new IllegalStateException("Method " + method + " returns a non-parameterized collection");
}
returnedContentType = ((ParameterizedType) returnType).getActualTypeArguments()[0];
collectionSpecification = new CollectionSpecification();
} else {
returnedContentType = method.getReturnType();
collectionSpecification = null;
}
ItemPath itemPath = getJaxbName(method);
String jpaName = getJpaName(method);
Class jpaClass = getClass(returnedContentType);
// sanity check
if (Set.class.isAssignableFrom(jpaClass)) {
throw new IllegalStateException("Collection within collection is not supported: method=" + method);
}
JpaLinkDefinition<? extends JpaDataNodeDefinition> linkDefinition;
Any any = method.getAnnotation(Any.class);
if (any != null) {
JpaAnyContainerDefinition targetDefinition = new JpaAnyContainerDefinition(jpaClass);
QName jaxbNameForAny = new QName(any.jaxbNameNamespace(), any.jaxbNameLocalPart());
linkDefinition = new JpaLinkDefinition<>(jaxbNameForAny, jpaName, collectionSpecification, false, targetDefinition);
} else if (ObjectReference.class.isAssignableFrom(jpaClass)) {
boolean embedded = method.isAnnotationPresent(Embedded.class);
// computing referenced entity type from returned content type like RObjectReference<RFocus> or REmbeddedReference<RRole>
Class referencedJpaClass;
if (returnedContentType instanceof ParameterizedType) {
referencedJpaClass = getClass(((ParameterizedType) returnedContentType).getActualTypeArguments()[0]);
} else {
referencedJpaClass = RObject.class;
}
JpaReferenceDefinition targetDefinition = new JpaReferenceDefinition(jpaClass, referencedJpaClass);
linkDefinition = new JpaLinkDefinition<>(itemPath, jpaName, collectionSpecification, embedded, targetDefinition);
} else if (isEntity(jpaClass)) {
JpaEntityDefinition content = parseClass(jpaClass);
boolean embedded = method.isAnnotationPresent(Embedded.class) || jpaClass.isAnnotationPresent(Embeddable.class);
linkDefinition = new JpaLinkDefinition<JpaDataNodeDefinition>(itemPath, jpaName, collectionSpecification, embedded, content);
} else {
boolean lob = method.isAnnotationPresent(Lob.class);
boolean enumerated = method.isAnnotationPresent(Enumerated.class);
//todo implement also lookup for @Table indexes
boolean indexed = method.isAnnotationPresent(Index.class);
boolean count = method.isAnnotationPresent(Count.class);
Class jaxbClass = getJaxbClass(method, jpaClass);
if (method.isAnnotationPresent(IdQueryProperty.class)) {
if (collectionSpecification != null) {
throw new IllegalStateException("ID property is not allowed to be multivalued; for method " + method);
}
itemPath = new ItemPath(new IdentifierPathSegment());
} else if (method.isAnnotationPresent(OwnerIdGetter.class)) {
if (collectionSpecification != null) {
throw new IllegalStateException("Owner ID property is not allowed to be multivalued; for method " + method);
}
itemPath = new ItemPath(new ParentPathSegment(), new IdentifierPathSegment());
}
JpaPropertyDefinition propertyDefinition = new JpaPropertyDefinition(jpaClass, jaxbClass, lob, enumerated, indexed, count);
// Note that properties are considered to be embedded
linkDefinition = new JpaLinkDefinition<JpaDataNodeDefinition>(itemPath, jpaName, collectionSpecification, true, propertyDefinition);
}
return linkDefinition;
}
use of com.evolveum.midpoint.prism.path.ParentPathSegment in project midpoint by Evolveum.
the class ClassDefinitionParser method parseClass.
private JpaEntityDefinition parseClass(Class jpaClass) {
Class jaxbClass = getJaxbClassForEntity(jpaClass);
JpaEntityDefinition entity = new JpaEntityDefinition(jpaClass, jaxbClass);
LOGGER.trace("### {}", entity);
addVirtualDefinitions(jpaClass, entity);
Method[] methods = jpaClass.getMethods();
for (Method method : methods) {
String methodName = method.getName();
if (Modifier.isStatic(method.getModifiers()) || "getClass".equals(methodName) || (!methodName.startsWith("is") && !methodName.startsWith("get")) || method.getAnnotation(NotQueryable.class) != null) {
//it's not getter for queryable property
continue;
}
if (method.isAnnotationPresent(Transient.class)) {
continue;
}
LOGGER.trace("# {}", method);
JpaLinkDefinition linkDefinition;
OwnerGetter ownerGetter = method.getAnnotation(OwnerGetter.class);
if (ownerGetter != null) {
String jpaName = getJpaName(method);
JpaDataNodeDefinition nodeDefinition = new JpaEntityPointerDefinition(ownerGetter.ownerClass());
// Owner is considered as not embedded, so we generate left outer join to access it
// (instead of implicit inner join that would be used if we would do x.owner.y = '...')
linkDefinition = new JpaLinkDefinition(new ParentPathSegment(), jpaName, null, false, nodeDefinition);
} else {
linkDefinition = parseMethod(method);
}
entity.addDefinition(linkDefinition);
}
return entity;
}
use of com.evolveum.midpoint.prism.path.ParentPathSegment in project midpoint by Evolveum.
the class ComplexTypeDefinitionImpl method findItemDefinition.
@Override
public <ID extends ItemDefinition> ID findItemDefinition(@NotNull ItemPath path, @NotNull Class<ID> clazz) {
for (; ; ) {
if (path.isEmpty()) {
throw new IllegalArgumentException("Cannot resolve empty path on complex type definition " + this);
}
ItemPathSegment first = path.first();
if (first instanceof NameItemPathSegment) {
QName firstName = ((NameItemPathSegment) first).getName();
return findNamedItemDefinition(firstName, path.rest(), clazz);
} else if (first instanceof IdItemPathSegment) {
path = path.rest();
} else if (first instanceof ParentPathSegment) {
ItemPath rest = path.rest();
ComplexTypeDefinition parent = getSchemaRegistry().determineParentDefinition(this, rest);
if (rest.isEmpty()) {
// requires that the parent is defined as an item (container, object)
return (ID) getSchemaRegistry().findItemDefinitionByType(parent.getTypeName());
} else {
return parent.findItemDefinition(rest, clazz);
}
} else if (first instanceof ObjectReferencePathSegment) {
throw new IllegalStateException("Couldn't use '@' path segment in this context. CTD=" + getTypeName() + ", path=" + path);
} else {
throw new IllegalStateException("Unexpected path segment: " + first + " in " + path);
}
}
}
use of com.evolveum.midpoint.prism.path.ParentPathSegment in project midpoint by Evolveum.
the class PrismContainerDefinitionImpl method findItemDefinition.
public <ID extends ItemDefinition> ID findItemDefinition(@NotNull ItemPath path, @NotNull Class<ID> clazz) {
for (; ; ) {
if (path.isEmpty()) {
if (clazz.isAssignableFrom(PrismContainerDefinition.class)) {
return (ID) this;
} else {
return null;
}
}
ItemPathSegment first = path.first();
if (first instanceof NameItemPathSegment) {
QName firstName = ((NameItemPathSegment) first).getName();
return findNamedItemDefinition(firstName, path.rest(), clazz);
} else if (first instanceof IdItemPathSegment) {
path = path.rest();
} else if (first instanceof ParentPathSegment) {
ItemPath rest = path.rest();
ComplexTypeDefinition parent = getSchemaRegistry().determineParentDefinition(getComplexTypeDefinition(), rest);
if (rest.isEmpty()) {
// requires that the parent is defined as an item (container, object)
return (ID) getSchemaRegistry().findItemDefinitionByType(parent.getTypeName());
} else {
return parent.findItemDefinition(rest, clazz);
}
} else if (first instanceof ObjectReferencePathSegment) {
throw new IllegalStateException("Couldn't use '@' path segment in this context. PCD=" + getTypeName() + ", path=" + path);
} else {
throw new IllegalStateException("Unexpected path segment: " + first + " in " + path);
}
}
}
use of com.evolveum.midpoint.prism.path.ParentPathSegment in project midpoint by Evolveum.
the class ModelController method resolve.
// TODO clean this mess
private <O extends ObjectType> void resolve(Containerable containerable, ItemPath path, SelectorOptions<GetOperationOptions> option, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, SecurityViolationException, ConfigurationException {
if (path == null || path.isEmpty()) {
return;
}
ItemPathSegment first = path.first();
ItemPath rest = path.rest();
PrismContainerValue<?> containerValue = containerable.asPrismContainerValue();
if (first instanceof NameItemPathSegment) {
QName refName = ItemPath.getName(first);
PrismReference reference = containerValue.findReferenceByCompositeObjectElementName(refName);
if (reference == null) {
// alternatively look up by reference name (e.g. linkRef)
reference = containerValue.findReference(refName);
}
if (reference != null) {
for (PrismReferenceValue refVal : reference.getValues()) {
PrismObject<O> refObject = refVal.getObject();
if (refObject == null) {
refObject = objectResolver.resolve(refVal, containerable.toString(), option.getOptions(), task, result);
refObject = refObject.cloneIfImmutable();
schemaTransformer.applySchemasAndSecurity(refObject, option.getOptions(), null, task, result);
refVal.setObject(refObject);
}
if (!rest.isEmpty()) {
resolve(refObject.asObjectable(), rest, option, task, result);
}
}
return;
}
}
if (rest.isEmpty()) {
return;
}
if (first instanceof ParentPathSegment) {
PrismContainerValue<?> parent = containerValue.getParentContainerValue();
if (parent != null) {
resolve(parent.asContainerable(), rest, option, task, result);
}
} else {
QName nextName = ItemPath.getName(first);
PrismContainer<?> nextContainer = containerValue.findContainer(nextName);
if (nextContainer != null) {
for (PrismContainerValue<?> pcv : nextContainer.getValues()) {
resolve(pcv.asContainerable(), rest, option, task, result);
}
}
}
}
Aggregations