Search in sources :

Example 1 with ParentPathSegment

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;
}
Also used : RPolyString(com.evolveum.midpoint.repo.sql.data.common.embedded.RPolyString) ParameterizedType(java.lang.reflect.ParameterizedType) ObjectReference(com.evolveum.midpoint.repo.sql.data.common.ObjectReference) RObject(com.evolveum.midpoint.repo.sql.data.common.RObject) Embedded(javax.persistence.Embedded) IdentifierPathSegment(com.evolveum.midpoint.prism.path.IdentifierPathSegment) ParentPathSegment(com.evolveum.midpoint.prism.path.ParentPathSegment) QName(javax.xml.namespace.QName) Embeddable(javax.persistence.Embeddable) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) ItemPath(com.evolveum.midpoint.prism.path.ItemPath)

Example 2 with ParentPathSegment

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;
}
Also used : ParentPathSegment(com.evolveum.midpoint.prism.path.ParentPathSegment) Method(java.lang.reflect.Method) RPolyString(com.evolveum.midpoint.repo.sql.data.common.embedded.RPolyString)

Example 3 with ParentPathSegment

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);
        }
    }
}
Also used : ItemPathSegment(com.evolveum.midpoint.prism.path.ItemPathSegment) IdItemPathSegment(com.evolveum.midpoint.prism.path.IdItemPathSegment) NameItemPathSegment(com.evolveum.midpoint.prism.path.NameItemPathSegment) ParentPathSegment(com.evolveum.midpoint.prism.path.ParentPathSegment) QName(javax.xml.namespace.QName) IdItemPathSegment(com.evolveum.midpoint.prism.path.IdItemPathSegment) ObjectReferencePathSegment(com.evolveum.midpoint.prism.path.ObjectReferencePathSegment) NameItemPathSegment(com.evolveum.midpoint.prism.path.NameItemPathSegment) ItemPath(com.evolveum.midpoint.prism.path.ItemPath)

Example 4 with ParentPathSegment

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);
        }
    }
}
Also used : ItemPathSegment(com.evolveum.midpoint.prism.path.ItemPathSegment) IdItemPathSegment(com.evolveum.midpoint.prism.path.IdItemPathSegment) NameItemPathSegment(com.evolveum.midpoint.prism.path.NameItemPathSegment) ParentPathSegment(com.evolveum.midpoint.prism.path.ParentPathSegment) QName(javax.xml.namespace.QName) IdItemPathSegment(com.evolveum.midpoint.prism.path.IdItemPathSegment) ObjectReferencePathSegment(com.evolveum.midpoint.prism.path.ObjectReferencePathSegment) NameItemPathSegment(com.evolveum.midpoint.prism.path.NameItemPathSegment) ItemPath(com.evolveum.midpoint.prism.path.ItemPath)

Example 5 with ParentPathSegment

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);
            }
        }
    }
}
Also used : ItemPathSegment(com.evolveum.midpoint.prism.path.ItemPathSegment) NameItemPathSegment(com.evolveum.midpoint.prism.path.NameItemPathSegment) ParentPathSegment(com.evolveum.midpoint.prism.path.ParentPathSegment) QName(javax.xml.namespace.QName) NameItemPathSegment(com.evolveum.midpoint.prism.path.NameItemPathSegment) ItemPath(com.evolveum.midpoint.prism.path.ItemPath)

Aggregations

ParentPathSegment (com.evolveum.midpoint.prism.path.ParentPathSegment)5 ItemPath (com.evolveum.midpoint.prism.path.ItemPath)4 QName (javax.xml.namespace.QName)4 ItemPathSegment (com.evolveum.midpoint.prism.path.ItemPathSegment)3 NameItemPathSegment (com.evolveum.midpoint.prism.path.NameItemPathSegment)3 IdItemPathSegment (com.evolveum.midpoint.prism.path.IdItemPathSegment)2 ObjectReferencePathSegment (com.evolveum.midpoint.prism.path.ObjectReferencePathSegment)2 RPolyString (com.evolveum.midpoint.repo.sql.data.common.embedded.RPolyString)2 IdentifierPathSegment (com.evolveum.midpoint.prism.path.IdentifierPathSegment)1 ObjectReference (com.evolveum.midpoint.repo.sql.data.common.ObjectReference)1 RObject (com.evolveum.midpoint.repo.sql.data.common.RObject)1 Method (java.lang.reflect.Method)1 ParameterizedType (java.lang.reflect.ParameterizedType)1 Type (java.lang.reflect.Type)1 Embeddable (javax.persistence.Embeddable)1 Embedded (javax.persistence.Embedded)1