use of com.evolveum.midpoint.common.refinery.RefinedAssociationDefinition in project midpoint by Evolveum.
the class OutboundProcessor method processOutbound.
public <F extends FocusType> void processOutbound(LensContext<F> context, LensProjectionContext projCtx, Task task, OperationResult result) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException {
ResourceShadowDiscriminator discr = projCtx.getResourceShadowDiscriminator();
ObjectDelta<ShadowType> projectionDelta = projCtx.getDelta();
if (projectionDelta != null && projectionDelta.getChangeType() == ChangeType.DELETE) {
LOGGER.trace("Processing outbound expressions for {} skipped, DELETE account delta", discr);
// No point in evaluating outbound
return;
}
LOGGER.trace("Processing outbound expressions for {} starting", discr);
RefinedObjectClassDefinition rOcDef = projCtx.getStructuralObjectClassDefinition();
if (rOcDef == null) {
LOGGER.error("Definition for {} not found in the context, but it should be there, dumping context:\n{}", discr, context.debugDump());
throw new IllegalStateException("Definition for " + discr + " not found in the context, but it should be there");
}
ObjectDeltaObject<F> focusOdo = context.getFocusContext().getObjectDeltaObject();
ObjectDeltaObject<ShadowType> projectionOdo = projCtx.getObjectDeltaObject();
Construction<F> outboundConstruction = new Construction<>(null, projCtx.getResource());
outboundConstruction.setRefinedObjectClassDefinition(rOcDef);
Collection<RefinedObjectClassDefinition> auxiliaryObjectClassDefinitions = rOcDef.getAuxiliaryObjectClassDefinitions();
if (auxiliaryObjectClassDefinitions != null) {
for (RefinedObjectClassDefinition auxiliaryObjectClassDefinition : auxiliaryObjectClassDefinitions) {
outboundConstruction.addAuxiliaryObjectClassDefinition(auxiliaryObjectClassDefinition);
}
}
String operation = projCtx.getOperation().getValue();
for (QName attributeName : rOcDef.getNamesOfAttributesWithOutboundExpressions()) {
RefinedAttributeDefinition<?> refinedAttributeDefinition = rOcDef.findAttributeDefinition(attributeName);
final MappingType outboundMappingType = refinedAttributeDefinition.getOutboundMappingType();
if (outboundMappingType == null) {
continue;
}
if (refinedAttributeDefinition.isIgnored(LayerType.MODEL)) {
LOGGER.trace("Skipping processing outbound mapping for attribute {} because it is ignored", attributeName);
continue;
}
Mapping.Builder<PrismPropertyValue<?>, RefinedAttributeDefinition<?>> builder = mappingFactory.createMappingBuilder(outboundMappingType, "outbound mapping for " + PrettyPrinter.prettyPrint(refinedAttributeDefinition.getName()) + " in " + rOcDef.getResourceType());
builder = builder.originObject(rOcDef.getResourceType()).originType(OriginType.OUTBOUND);
Mapping<PrismPropertyValue<?>, RefinedAttributeDefinition<?>> evaluatedMapping = evaluateMapping(builder, attributeName, refinedAttributeDefinition, focusOdo, projectionOdo, operation, rOcDef, null, context, projCtx, task, result);
if (evaluatedMapping != null) {
outboundConstruction.addAttributeMapping(evaluatedMapping);
}
}
for (QName assocName : rOcDef.getNamesOfAssociationsWithOutboundExpressions()) {
RefinedAssociationDefinition associationDefinition = rOcDef.findAssociationDefinition(assocName);
final MappingType outboundMappingType = associationDefinition.getOutboundMappingType();
if (outboundMappingType == null) {
continue;
}
// if (associationDefinition.isIgnored(LayerType.MODEL)) {
// LOGGER.trace("Skipping processing outbound mapping for attribute {} because it is ignored", assocName);
// continue;
// }
Mapping.Builder<PrismContainerValue<ShadowAssociationType>, PrismContainerDefinition<ShadowAssociationType>> mappingBuilder = mappingFactory.createMappingBuilder(outboundMappingType, "outbound mapping for " + PrettyPrinter.prettyPrint(associationDefinition.getName()) + " in " + rOcDef.getResourceType());
PrismContainerDefinition<ShadowAssociationType> outputDefinition = getAssociationContainerDefinition();
Mapping<PrismContainerValue<ShadowAssociationType>, PrismContainerDefinition<ShadowAssociationType>> evaluatedMapping = (Mapping) evaluateMapping(mappingBuilder, assocName, outputDefinition, focusOdo, projectionOdo, operation, rOcDef, associationDefinition.getAssociationTarget(), context, projCtx, task, result);
if (evaluatedMapping != null) {
outboundConstruction.addAssociationMapping(evaluatedMapping);
}
}
projCtx.setOutboundConstruction(outboundConstruction);
}
use of com.evolveum.midpoint.common.refinery.RefinedAssociationDefinition in project midpoint by Evolveum.
the class ShadowManager method createRepositoryShadow.
/**
* Create a copy of a shadow that is suitable for repository storage.
*/
private PrismObject<ShadowType> createRepositoryShadow(ProvisioningContext ctx, PrismObject<ShadowType> shadow) throws SchemaException, ConfigurationException, ObjectNotFoundException, CommunicationException, ExpressionEvaluationException {
ResourceAttributeContainer attributesContainer = ShadowUtil.getAttributesContainer(shadow);
PrismObject<ShadowType> repoShadow = shadow.clone();
ShadowType repoShadowType = repoShadow.asObjectable();
ResourceAttributeContainer repoAttributesContainer = ShadowUtil.getAttributesContainer(repoShadow);
CachingStategyType cachingStrategy = ProvisioningUtil.getCachingStrategy(ctx);
if (cachingStrategy == CachingStategyType.NONE) {
// Clean all repoShadow attributes and add only those that should be
// there
repoAttributesContainer.clear();
Collection<ResourceAttribute<?>> primaryIdentifiers = attributesContainer.getPrimaryIdentifiers();
for (PrismProperty<?> p : primaryIdentifiers) {
repoAttributesContainer.add(p.clone());
}
Collection<ResourceAttribute<?>> secondaryIdentifiers = attributesContainer.getSecondaryIdentifiers();
for (PrismProperty<?> p : secondaryIdentifiers) {
repoAttributesContainer.add(p.clone());
}
// Also add all the attributes that act as association identifiers.
// We will need them when the shadow is deleted (to remove the shadow from entitlements).
RefinedObjectClassDefinition objectClassDefinition = ctx.getObjectClassDefinition();
for (RefinedAssociationDefinition associationDef : objectClassDefinition.getAssociationDefinitions()) {
if (associationDef.getResourceObjectAssociationType().getDirection() == ResourceObjectAssociationDirectionType.OBJECT_TO_SUBJECT) {
QName valueAttributeName = associationDef.getResourceObjectAssociationType().getValueAttribute();
if (repoAttributesContainer.findAttribute(valueAttributeName) == null) {
ResourceAttribute<Object> valueAttribute = attributesContainer.findAttribute(valueAttributeName);
if (valueAttribute != null) {
repoAttributesContainer.add(valueAttribute.clone());
}
}
}
}
repoShadowType.setCachingMetadata(null);
ProvisioningUtil.cleanupShadowActivation(repoShadowType);
} else if (cachingStrategy == CachingStategyType.PASSIVE) {
// Do not need to clear anything. Just store all attributes and add metadata.
CachingMetadataType cachingMetadata = new CachingMetadataType();
cachingMetadata.setRetrievalTimestamp(clock.currentTimeXMLGregorianCalendar());
repoShadowType.setCachingMetadata(cachingMetadata);
} else {
throw new ConfigurationException("Unknown caching strategy " + cachingStrategy);
}
setKindIfNecessary(repoShadowType, ctx.getObjectClassDefinition());
// setIntentIfNecessary(repoShadowType, objectClassDefinition);
// Store only password meta-data in repo
CredentialsType creds = repoShadowType.getCredentials();
if (creds != null) {
PasswordType passwordType = creds.getPassword();
if (passwordType != null) {
ProvisioningUtil.cleanupShadowPassword(passwordType);
PrismObject<UserType> owner = null;
if (ctx.getTask() != null) {
owner = ctx.getTask().getOwner();
}
ProvisioningUtil.addPasswordMetadata(passwordType, clock.currentTimeXMLGregorianCalendar(), owner);
}
// TODO: other credential types - later
}
// convert to the resource reference.
if (repoShadowType.getResource() != null) {
repoShadowType.setResource(null);
repoShadowType.setResourceRef(ObjectTypeUtil.createObjectRef(ctx.getResource()));
}
// now
if (repoShadowType.getResourceRef() == null) {
repoShadowType.setResourceRef(ObjectTypeUtil.createObjectRef(ctx.getResource()));
}
if (repoShadowType.getName() == null) {
repoShadowType.setName(new PolyStringType(ShadowUtil.determineShadowName(shadow)));
}
if (repoShadowType.getObjectClass() == null) {
repoShadowType.setObjectClass(attributesContainer.getDefinition().getTypeName());
}
if (repoShadowType.isProtectedObject() != null) {
repoShadowType.setProtectedObject(null);
}
normalizeAttributes(repoShadow, ctx.getObjectClassDefinition());
return repoShadow;
}
use of com.evolveum.midpoint.common.refinery.RefinedAssociationDefinition in project midpoint by Evolveum.
the class ContainerWrapperFactory method createProperties.
private List<ItemWrapper> createProperties(ContainerWrapper cWrapper, OperationResult result) {
ObjectWrapper objectWrapper = cWrapper.getObject();
PrismContainer container = cWrapper.getItem();
PrismContainerDefinition containerDefinition = cWrapper.getItemDefinition();
List<ItemWrapper> properties = new ArrayList<>();
PrismContainerDefinition definition;
if (objectWrapper == null) {
definition = containerDefinition;
} else {
PrismObject parent = objectWrapper.getObject();
Class clazz = parent.getCompileTimeClass();
if (ShadowType.class.isAssignableFrom(clazz)) {
QName name = containerDefinition.getName();
if (ShadowType.F_ATTRIBUTES.equals(name)) {
try {
definition = objectWrapper.getRefinedAttributeDefinition();
if (definition == null) {
PrismReference resourceRef = parent.findReference(ShadowType.F_RESOURCE_REF);
PrismObject<ResourceType> resource = resourceRef.getValue().getObject();
definition = modelServiceLocator.getModelInteractionService().getEditObjectClassDefinition((PrismObject<ShadowType>) objectWrapper.getObject(), resource, AuthorizationPhaseType.REQUEST).toResourceAttributeContainerDefinition();
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Refined account def:\n{}", definition.debugDump());
}
}
} catch (Exception ex) {
LoggingUtils.logUnexpectedException(LOGGER, "Couldn't load definitions from refined schema for shadow", ex);
result.recordFatalError("Couldn't load definitions from refined schema for shadow, reason: " + ex.getMessage(), ex);
return properties;
}
} else {
definition = containerDefinition;
}
} else if (ResourceType.class.isAssignableFrom(clazz)) {
if (containerDefinition != null) {
definition = containerDefinition;
} else {
definition = container.getDefinition();
}
} else {
definition = containerDefinition;
}
}
if (definition == null) {
LOGGER.error("Couldn't get property list from null definition {}", new Object[] { container.getElementName() });
return properties;
}
// they are filtered out by ObjectWrapper)
if (container.getCompileTimeClass() != null && AssignmentType.class.isAssignableFrom(container.getCompileTimeClass())) {
for (Object o : container.getValues()) {
PrismContainerValue<AssignmentType> pcv = (PrismContainerValue<AssignmentType>) o;
AssignmentType assignmentType = pcv.asContainerable();
if (assignmentType.getTargetRef() == null) {
continue;
}
// hack... we want to create a definition for Name
// PrismPropertyDefinition def = ((PrismContainerValue)
// pcv.getContainer().getParent()).getContainer().findProperty(ObjectType.F_NAME).getDefinition();
PrismPropertyDefinitionImpl def = new PrismPropertyDefinitionImpl(ObjectType.F_NAME, DOMUtil.XSD_STRING, pcv.getPrismContext());
if (OrgType.COMPLEX_TYPE.equals(assignmentType.getTargetRef().getType())) {
def.setDisplayName("Org.Unit");
def.setDisplayOrder(100);
} else if (RoleType.COMPLEX_TYPE.equals(assignmentType.getTargetRef().getType())) {
def.setDisplayName("Role");
def.setDisplayOrder(200);
} else {
continue;
}
PrismProperty<Object> temp = def.instantiate();
String value = formatAssignmentBrief(assignmentType);
temp.setValue(new PrismPropertyValue<Object>(value));
// TODO: do this.isReadOnly() - is that OK? (originally it was the default behavior for all cases)
properties.add(new PropertyWrapper(cWrapper, temp, cWrapper.isReadonly(), ValueStatus.NOT_CHANGED));
}
} else if (isShadowAssociation(cWrapper)) {
// HACK: this should not be here. Find a better place.
cWrapper.setDisplayName("prismContainer.shadow.associations");
PrismContext prismContext = objectWrapper.getObject().getPrismContext();
Map<QName, PrismContainer<ShadowAssociationType>> assocMap = new HashMap<>();
PrismContainer<ShadowAssociationType> associationContainer = cWrapper.getItem();
if (associationContainer != null && associationContainer.getValues() != null) {
// Do NOT load shadows here. This will be huge overhead if there are many associations.
// Load them on-demand (if necessary at all).
List<PrismContainerValue<ShadowAssociationType>> associations = associationContainer.getValues();
if (associations != null) {
for (PrismContainerValue<ShadowAssociationType> cval : associations) {
ShadowAssociationType associationType = cval.asContainerable();
QName assocName = associationType.getName();
PrismContainer<ShadowAssociationType> fractionalContainer = assocMap.get(assocName);
if (fractionalContainer == null) {
fractionalContainer = new PrismContainer<>(ShadowType.F_ASSOCIATION, ShadowAssociationType.class, cval.getPrismContext());
fractionalContainer.setDefinition(cval.getParent().getDefinition());
// HACK: set the name of the association as the element name so wrapper.getName() will return correct data.
fractionalContainer.setElementName(assocName);
assocMap.put(assocName, fractionalContainer);
}
try {
fractionalContainer.add(cval.clone());
} catch (SchemaException e) {
// Should not happen
throw new SystemException("Unexpected error: " + e.getMessage(), e);
}
}
}
}
PrismReference resourceRef = objectWrapper.getObject().findReference(ShadowType.F_RESOURCE_REF);
PrismObject<ResourceType> resource = resourceRef.getValue().getObject();
// of resources.
try {
resource.revive(prismContext);
} catch (SchemaException e) {
throw new SystemException(e.getMessage(), e);
}
RefinedResourceSchema refinedSchema;
CompositeRefinedObjectClassDefinition rOcDef;
try {
refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource);
rOcDef = refinedSchema.determineCompositeObjectClassDefinition(objectWrapper.getObject());
} catch (SchemaException e) {
throw new SystemException(e.getMessage(), e);
}
// Make sure even empty associations have their wrappers so they can be displayed and edited
for (RefinedAssociationDefinition assocDef : rOcDef.getAssociationDefinitions()) {
QName name = assocDef.getName();
if (!assocMap.containsKey(name)) {
PrismContainer<ShadowAssociationType> fractionalContainer = new PrismContainer<>(ShadowType.F_ASSOCIATION, ShadowAssociationType.class, prismContext);
fractionalContainer.setDefinition(cWrapper.getItemDefinition());
// HACK: set the name of the association as the element name so wrapper.getName() will return correct data.
fractionalContainer.setElementName(name);
assocMap.put(name, fractionalContainer);
}
}
for (Map.Entry<QName, PrismContainer<ShadowAssociationType>> assocEntry : assocMap.entrySet()) {
RefinedAssociationDefinition assocRDef = rOcDef.findAssociationDefinition(assocEntry.getKey());
AssociationWrapper assocWrapper = new AssociationWrapper(cWrapper, assocEntry.getValue(), cWrapper.isReadonly(), ValueStatus.NOT_CHANGED, assocRDef);
properties.add(assocWrapper);
}
} else {
if ((container.getValues().size() == 1 || container.getValues().isEmpty()) && (containerDefinition == null || containerDefinition.isSingleValue())) {
// there's no point in showing properties for non-single-valued
// parent containers,
// so we continue only if the parent is single-valued
Collection<ItemDefinition> propertyDefinitions = definition.getDefinitions();
for (ItemDefinition itemDef : propertyDefinitions) {
//TODO temporary decision to hide adminGuiConfiguration attribute (MID-3305)
if (itemDef != null && itemDef.getName() != null && itemDef.getName().getLocalPart() != null && itemDef.getName().getLocalPart().equals("adminGuiConfiguration")) {
continue;
}
if (itemDef instanceof PrismPropertyDefinition) {
PrismPropertyDefinition def = (PrismPropertyDefinition) itemDef;
if (def.isIgnored() || skipProperty(def)) {
continue;
}
if (!cWrapper.isShowInheritedObjectAttributes() && INHERITED_OBJECT_ATTRIBUTES.contains(def.getName())) {
continue;
}
// capability handling for activation properties
if (isShadowActivation(cWrapper) && !hasActivationCapability(cWrapper, def)) {
continue;
}
if (isShadowAssociation(cWrapper)) {
continue;
}
PrismProperty property = container.findProperty(def.getName());
boolean propertyIsReadOnly;
// to an existing object)
if (objectWrapper == null || objectWrapper.getStatus() == ContainerStatus.MODIFYING) {
propertyIsReadOnly = cWrapper.isReadonly() || !def.canModify();
} else {
propertyIsReadOnly = cWrapper.isReadonly() || !def.canAdd();
}
if (property == null) {
properties.add(new PropertyWrapper(cWrapper, def.instantiate(), propertyIsReadOnly, ValueStatus.ADDED));
} else {
properties.add(new PropertyWrapper(cWrapper, property, propertyIsReadOnly, ValueStatus.NOT_CHANGED));
}
} else if (itemDef instanceof PrismReferenceDefinition) {
PrismReferenceDefinition def = (PrismReferenceDefinition) itemDef;
if (INHERITED_OBJECT_ATTRIBUTES.contains(def.getName())) {
continue;
}
PrismReference reference = container.findReference(def.getName());
boolean propertyIsReadOnly;
// to an existing object)
if (objectWrapper == null || objectWrapper.getStatus() == ContainerStatus.MODIFYING) {
propertyIsReadOnly = !def.canModify();
} else {
propertyIsReadOnly = !def.canAdd();
}
if (reference == null) {
properties.add(new ReferenceWrapper(cWrapper, def.instantiate(), propertyIsReadOnly, ValueStatus.ADDED));
} else {
properties.add(new ReferenceWrapper(cWrapper, reference, propertyIsReadOnly, ValueStatus.NOT_CHANGED));
}
}
}
}
}
Collections.sort(properties, new ItemWrapperComparator());
result.recomputeStatus();
return properties;
}
use of com.evolveum.midpoint.common.refinery.RefinedAssociationDefinition in project midpoint by Evolveum.
the class Construction method evaluateAssociation.
private Mapping<PrismContainerValue<ShadowAssociationType>, PrismContainerDefinition<ShadowAssociationType>> evaluateAssociation(ResourceObjectAssociationType associationDefinitionType, Task task, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException {
QName assocName = ItemPathUtil.getOnlySegmentQName(associationDefinitionType.getRef());
if (assocName == null) {
throw new SchemaException("Missing 'ref' in association in construction in " + getSource());
}
MappingType outboundMappingType = associationDefinitionType.getOutbound();
if (outboundMappingType == null) {
throw new SchemaException("No outbound section in definition of association " + assocName + " in construction in " + getSource());
}
PrismContainerDefinition<ShadowAssociationType> outputDefinition = getAssociationContainerDefinition();
Mapping.Builder<PrismContainerValue<ShadowAssociationType>, PrismContainerDefinition<ShadowAssociationType>> mappingBuilder = mappingFactory.<PrismContainerValue<ShadowAssociationType>, PrismContainerDefinition<ShadowAssociationType>>createMappingBuilder().mappingType(outboundMappingType).contextDescription("for association " + PrettyPrinter.prettyPrint(assocName) + " in " + getSource()).originType(OriginType.ASSIGNMENTS).originObject(getSource());
RefinedAssociationDefinition rAssocDef = refinedObjectClassDefinition.findAssociationDefinition(assocName);
if (rAssocDef == null) {
throw new SchemaException("No association " + assocName + " in object class " + refinedObjectClassDefinition.getHumanReadableName() + " in construction in " + getSource());
}
Mapping<PrismContainerValue<ShadowAssociationType>, PrismContainerDefinition<ShadowAssociationType>> evaluatedMapping = evaluateMapping(mappingBuilder, assocName, outputDefinition, rAssocDef.getAssociationTarget(), task, result);
LOGGER.trace("Evaluated mapping for association " + assocName + ": " + evaluatedMapping);
return evaluatedMapping;
}
use of com.evolveum.midpoint.common.refinery.RefinedAssociationDefinition in project midpoint by Evolveum.
the class ShadowCache method completeShadow.
/**
* Make sure that the shadow is complete, e.g. that all the mandatory fields
* are filled (e.g name, resourceRef, ...) Also transforms the shadow with
* respect to simulated capabilities.
*/
private PrismObject<ShadowType> completeShadow(ProvisioningContext ctx, PrismObject<ShadowType> resourceShadow, PrismObject<ShadowType> repoShadow, OperationResult parentResult) throws SchemaException, ConfigurationException, ObjectNotFoundException, CommunicationException, SecurityViolationException, GenericConnectorException, ExpressionEvaluationException {
PrismObject<ShadowType> resultShadow = repoShadow.clone();
// The real definition may be different than that of repo shadow (e.g.
// different auxiliary object classes).
resultShadow.applyDefinition(ctx.getObjectClassDefinition().getObjectDefinition(), true);
assert resultShadow.getPrismContext() != null : "No prism context in resultShadow";
ResourceAttributeContainer resourceAttributesContainer = ShadowUtil.getAttributesContainer(resourceShadow);
ShadowType resultShadowType = resultShadow.asObjectable();
ShadowType repoShadowType = repoShadow.asObjectable();
ShadowType resourceShadowType = resourceShadow.asObjectable();
Collection<QName> auxObjectClassQNames = new ArrayList<>();
// Always take auxiliary object classes from the resource. Unlike
// structural object classes
// the auxiliary object classes may change.
resultShadow.removeProperty(ShadowType.F_AUXILIARY_OBJECT_CLASS);
PrismProperty<QName> resourceAuxOcProp = resourceShadow.findProperty(ShadowType.F_AUXILIARY_OBJECT_CLASS);
if (resourceAuxOcProp != null) {
PrismProperty<QName> resultAuxOcProp = resultShadow.findOrCreateProperty(ShadowType.F_AUXILIARY_OBJECT_CLASS);
resultAuxOcProp.addAll(PrismPropertyValue.cloneCollection(resourceAuxOcProp.getValues()));
auxObjectClassQNames.addAll(resultAuxOcProp.getRealValues());
}
resultShadowType.setName(new PolyStringType(ShadowUtil.determineShadowName(resourceShadow)));
if (resultShadowType.getObjectClass() == null) {
resultShadowType.setObjectClass(resourceAttributesContainer.getDefinition().getTypeName());
}
if (resultShadowType.getResource() == null) {
resultShadowType.setResourceRef(ObjectTypeUtil.createObjectRef(ctx.getResource()));
}
// Attributes
resultShadow.removeContainer(ShadowType.F_ATTRIBUTES);
ResourceAttributeContainer resultAttibutes = resourceAttributesContainer.clone();
accessChecker.filterGetAttributes(resultAttibutes, ctx.computeCompositeObjectClassDefinition(auxObjectClassQNames), parentResult);
resultShadow.add(resultAttibutes);
resultShadowType.setIgnored(resourceShadowType.isIgnored());
resultShadowType.setActivation(resourceShadowType.getActivation());
ShadowType resultAccountShadow = resultShadow.asObjectable();
ShadowType resourceAccountShadow = resourceShadow.asObjectable();
// Credentials
resultAccountShadow.setCredentials(resourceAccountShadow.getCredentials());
transplantPasswordMetadata(repoShadowType, resultAccountShadow);
// protected
ProvisioningUtil.setProtectedFlag(ctx, resultShadow, matchingRuleRegistry);
// exists, dead
resultShadowType.setExists(resourceShadowType.isExists());
// Activation
ActivationType resultActivationType = resultShadowType.getActivation();
ActivationType repoActivation = repoShadowType.getActivation();
if (repoActivation != null) {
if (resultActivationType == null) {
resultActivationType = new ActivationType();
resultShadowType.setActivation(resultActivationType);
}
resultActivationType.setId(repoActivation.getId());
// .. but we want metadata from repo
resultActivationType.setDisableReason(repoActivation.getDisableReason());
resultActivationType.setEnableTimestamp(repoActivation.getEnableTimestamp());
resultActivationType.setDisableTimestamp(repoActivation.getDisableTimestamp());
resultActivationType.setArchiveTimestamp(repoActivation.getArchiveTimestamp());
resultActivationType.setValidityChangeTimestamp(repoActivation.getValidityChangeTimestamp());
}
// Associations
PrismContainer<ShadowAssociationType> resourceAssociationContainer = resourceShadow.findContainer(ShadowType.F_ASSOCIATION);
if (resourceAssociationContainer != null) {
PrismContainer<ShadowAssociationType> associationContainer = resourceAssociationContainer.clone();
resultShadow.addReplaceExisting(associationContainer);
if (associationContainer != null) {
for (PrismContainerValue<ShadowAssociationType> associationCVal : associationContainer.getValues()) {
ResourceAttributeContainer identifierContainer = ShadowUtil.getAttributesContainer(associationCVal, ShadowAssociationType.F_IDENTIFIERS);
Collection<ResourceAttribute<?>> entitlementIdentifiers = identifierContainer.getAttributes();
if (entitlementIdentifiers == null || entitlementIdentifiers.isEmpty()) {
throw new IllegalStateException("No entitlement identifiers present for association " + associationCVal + " " + ctx.getDesc());
}
ShadowAssociationType shadowAssociationType = associationCVal.asContainerable();
QName associationName = shadowAssociationType.getName();
RefinedAssociationDefinition rEntitlementAssociation = ctx.getObjectClassDefinition().findAssociationDefinition(associationName);
if (rEntitlementAssociation == null) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Entitlement association with name {} couldn't be found in {} {}\nresource shadow:\n{}\nrepo shadow:\n{}", new Object[] { associationName, ctx.getObjectClassDefinition(), ctx.getDesc(), resourceShadow.debugDump(1), repoShadow == null ? null : repoShadow.debugDump(1) });
LOGGER.trace("Full refined definition: {}", ctx.getObjectClassDefinition().debugDump());
}
throw new SchemaException("Entitlement association with name " + associationName + " couldn't be found in " + ctx.getObjectClassDefinition() + " " + ctx.getDesc() + ", with using shadow coordinates " + ctx.isUseRefinedDefinition());
}
ShadowKindType entitlementKind = rEntitlementAssociation.getKind();
if (entitlementKind == null) {
entitlementKind = ShadowKindType.ENTITLEMENT;
}
for (String entitlementIntent : rEntitlementAssociation.getIntents()) {
ProvisioningContext ctxEntitlement = ctx.spawn(entitlementKind, entitlementIntent);
PrismObject<ShadowType> entitlementRepoShadow;
PrismObject<ShadowType> entitlementShadow = (PrismObject<ShadowType>) identifierContainer.getUserData(ResourceObjectConverter.FULL_SHADOW_KEY);
if (entitlementShadow == null) {
try {
entitlementRepoShadow = shadowManager.lookupShadowInRepository(ctxEntitlement, identifierContainer, parentResult);
if (entitlementRepoShadow == null) {
entitlementShadow = resouceObjectConverter.locateResourceObject(ctxEntitlement, entitlementIdentifiers, parentResult);
// Try to look up repo shadow again, this
// time with full resource shadow. When we
// have searched before we might
// have only some identifiers. The shadow
// might still be there, but it may be
// renamed
entitlementRepoShadow = shadowManager.lookupShadowInRepository(ctxEntitlement, entitlementShadow, parentResult);
if (entitlementRepoShadow == null) {
entitlementRepoShadow = createShadowInRepository(ctxEntitlement, entitlementShadow, false, parentResult);
}
}
} catch (ObjectNotFoundException e) {
// The entitlement to which we point is not
// there.
// Simply ignore this association value.
parentResult.muteLastSubresultError();
LOGGER.warn("The entitlement identified by {} referenced from {} does not exist. Skipping.", new Object[] { associationCVal, resourceShadow });
continue;
} catch (SchemaException e) {
// The entitlement to which we point is not bad.
// Simply ignore this association value.
parentResult.muteLastSubresultError();
LOGGER.warn("The entitlement identified by {} referenced from {} violates the schema. Skipping. Original error: {}", new Object[] { associationCVal, resourceShadow, e.getMessage(), e });
continue;
}
} else {
entitlementRepoShadow = lookupOrCreateShadowInRepository(ctxEntitlement, entitlementShadow, false, parentResult);
}
ObjectReferenceType shadowRefType = new ObjectReferenceType();
shadowRefType.setOid(entitlementRepoShadow.getOid());
shadowRefType.setType(ShadowType.COMPLEX_TYPE);
shadowAssociationType.setShadowRef(shadowRefType);
}
}
}
}
resultShadowType.setCachingMetadata(resourceShadowType.getCachingMetadata());
// Sanity asserts to catch some exotic bugs
PolyStringType resultName = resultShadow.asObjectable().getName();
assert resultName != null : "No name generated in " + resultShadow;
assert !StringUtils.isEmpty(resultName.getOrig()) : "No name (orig) in " + resultShadow;
assert !StringUtils.isEmpty(resultName.getNorm()) : "No name (norm) in " + resultShadow;
return resultShadow;
}
Aggregations