@Override public void setObject(Object object) { try { PrismProperty property = getPrismObject().findOrCreateProperty(path); if (object != null) { PrismPropertyDefinition def = property.getDefinition(); if (PolyString.class.equals(def.getTypeClass())) { object = new PolyString((String) object); } property.setValue(new PrismPropertyValue(object, OriginType.USER_ACTION, null)); } else { PrismContainerValue parent = (PrismContainerValue) property.getParent(); parent.remove(property); } } catch (Exception ex) { LoggingUtils.logException(LOGGER, "Couldn't update prism property model", ex); } }
private void fillInUserDrake(PrismObject<UserType> user, boolean assertDefinitions) throws SchemaException { user.setOid(USER_OID); // fullName PrismProperty<String> fullNameProperty = user.findOrCreateProperty(USER_FULLNAME_QNAME); assertEquals(USER_FULLNAME_QNAME, fullNameProperty.getElementName()); PrismAsserts.assertParentConsistency(user); if (assertDefinitions) PrismAsserts.assertDefinition(fullNameProperty, DOMUtil.XSD_STRING, 1, 1); fullNameProperty.setValue(new PrismPropertyValue<String>("Sir Fancis Drake")); PrismProperty<String> fullNamePropertyAgain = user.findOrCreateProperty(USER_FULLNAME_QNAME); // The "==" is there by purpose. We really want to make sure that is the same *instance*, that // is was not created again assertTrue("Property not the same", fullNameProperty == fullNamePropertyAgain); // activation PrismContainer<ActivationType> activationContainer = user.findOrCreateContainer(USER_ACTIVATION_QNAME); assertEquals(USER_ACTIVATION_QNAME, activationContainer.getElementName()); PrismAsserts.assertParentConsistency(user); if (assertDefinitions) PrismAsserts.assertDefinition(activationContainer, ACTIVATION_TYPE_QNAME, 0, 1); PrismContainer<ActivationType> activationContainerAgain = user.findOrCreateContainer(USER_ACTIVATION_QNAME); // The "==" is there by purpose. We really want to make sure that is the same *instance*, that // is was not created again assertTrue("Property not the same", activationContainer == activationContainerAgain); // activation/enabled PrismProperty<Boolean> enabledProperty = user.findOrCreateProperty(USER_ENABLED_PATH); assertEquals(USER_ENABLED_QNAME, enabledProperty.getElementName()); PrismAsserts.assertParentConsistency(user); if (assertDefinitions) PrismAsserts.assertDefinition(enabledProperty, DOMUtil.XSD_BOOLEAN, 0, 1); enabledProperty.setValue(new PrismPropertyValue<Boolean>(true)); PrismProperty<Boolean> enabledPropertyAgain = activationContainer.findOrCreateProperty(USER_ENABLED_QNAME); // The "==" is there by purpose. We really want to make sure that is the same *instance*, that // is was not created again assertTrue("Property not the same", enabledProperty == enabledPropertyAgain); // assignment // Try to create this one from the value. It should work the same, but let's test a different // code path PrismContainer<AssignmentType> assignmentContainer = user.getValue().findOrCreateContainer(USER_ASSIGNMENT_QNAME); assertEquals(USER_ASSIGNMENT_QNAME, assignmentContainer.getElementName()); PrismAsserts.assertParentConsistency(user); if (assertDefinitions) PrismAsserts.assertDefinition(assignmentContainer, ASSIGNMENT_TYPE_QNAME, 0, -1); PrismContainer<AssignmentType> assignmentContainerAgain = user.findOrCreateContainer(USER_ASSIGNMENT_QNAME); // The "==" is there by purpose. We really want to make sure that is the same *instance*, that // is was not created again assertTrue("Property not the same", assignmentContainer == assignmentContainerAgain); assertEquals( "Wrong number of assignment values (empty)", 0, assignmentContainer.getValues().size()); // assignment values: construct assignment value as a new container "out of the blue" and then // add it. PrismContainer<AssignmentType> assBlueContainer = new PrismContainer<AssignmentType>(USER_ASSIGNMENT_QNAME); PrismProperty<String> assBlueDescriptionProperty = assBlueContainer.findOrCreateProperty(USER_DESCRIPTION_QNAME); assBlueDescriptionProperty.addValue( new PrismPropertyValue<String>("Assignment created out of the blue")); PrismAsserts.assertParentConsistency(user); assignmentContainer.mergeValues(assBlueContainer); assertEquals( "Wrong number of assignment values (after blue)", 1, assignmentContainer.getValues().size()); PrismAsserts.assertParentConsistency(user); // assignment values: construct assignment value as a new container value "out of the blue" and // then add it. PrismContainerValue<AssignmentType> assCyanContainerValue = new PrismContainerValue<AssignmentType>(); PrismProperty<String> assCyanDescriptionProperty = assCyanContainerValue.findOrCreateProperty(USER_DESCRIPTION_QNAME); assCyanDescriptionProperty.addValue( new PrismPropertyValue<String>("Assignment created out of the cyan")); assignmentContainer.mergeValue(assCyanContainerValue); assertEquals( "Wrong number of assignment values (after cyan)", 2, assignmentContainer.getValues().size()); PrismAsserts.assertParentConsistency(user); // assignment values: construct assignment value from existing container PrismContainerValue<AssignmentType> assRedContainerValue = assignmentContainer.createNewValue(); PrismProperty<String> assRedDescriptionProperty = assRedContainerValue.findOrCreateProperty(USER_DESCRIPTION_QNAME); assRedDescriptionProperty.addValue( new PrismPropertyValue<String>("Assignment created out of the red")); assertEquals( "Wrong number of assignment values (after red)", 3, assignmentContainer.getValues().size()); PrismAsserts.assertParentConsistency(user); // accountRef PrismReference accountRef = user.findOrCreateReference(USER_ACCOUNTREF_QNAME); assertEquals(USER_ACCOUNTREF_QNAME, accountRef.getElementName()); if (assertDefinitions) PrismAsserts.assertDefinition(accountRef, OBJECT_REFERENCE_TYPE_QNAME, 0, -1); accountRef.add(new PrismReferenceValue(ACCOUNT1_OID)); accountRef.add(new PrismReferenceValue(ACCOUNT2_OID)); PrismReference accountRefAgain = user.findOrCreateReference(USER_ACCOUNTREF_QNAME); // The "==" is there by purpose. We really want to make sure that is the same *instance*, that // is was not created again assertTrue("Property not the same", accountRef == accountRefAgain); assertEquals("accountRef size", 2, accountRef.getValues().size()); PrismAsserts.assertParentConsistency(user); // extension PrismContainer<?> extensionContainer = user.findOrCreateContainer(USER_EXTENSION_QNAME); assertEquals(USER_EXTENSION_QNAME, extensionContainer.getElementName()); PrismAsserts.assertParentConsistency(user); if (assertDefinitions) PrismAsserts.assertDefinition(extensionContainer, DOMUtil.XSD_ANY, 0, 1); PrismContainer<AssignmentType> extensionContainerAgain = user.findOrCreateContainer(USER_EXTENSION_QNAME); // The "==" is there by purpose. We really want to make sure that is the same *instance*, that // is was not created again assertTrue("Extension not the same", extensionContainer == extensionContainerAgain); assertEquals( "Wrong number of extension values (empty)", 0, extensionContainer.getValues().size()); // extension / stringType PrismProperty<String> stringTypeProperty = extensionContainer.findOrCreateProperty(EXTENSION_STRING_TYPE_ELEMENT); assertEquals(EXTENSION_STRING_TYPE_ELEMENT, stringTypeProperty.getElementName()); PrismAsserts.assertParentConsistency(user); if (assertDefinitions) PrismAsserts.assertDefinition(stringTypeProperty, DOMUtil.XSD_STRING, 0, -1); // TODO }
private List<ItemWrapper> createProperties(PageBase pageBase) { result = new OperationResult(CREATE_PROPERTIES); List<ItemWrapper> properties = new ArrayList<ItemWrapper>(); PrismContainerDefinition definition = null; PrismObject parent = getObject().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 = pageBase .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.logException( 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; } // assignments are treated in a special way -- we display names of // org.units and roles // (but only if ObjectWrapper.isShowAssignments() is true; otherwise // 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(); PrismPropertyDefinition def = new PrismPropertyDefinition( 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(this, temp, this.isReadonly(), ValueStatus.NOT_CHANGED)); } } else if (isShadowAssociation()) { PrismContext prismContext = objectWrapper.getObject().getPrismContext(); Map<QName, PrismContainer<ShadowAssociationType>> assocMap = new HashMap<>(); if (objectWrapper.getAssociations() != null) { for (PrismContainerValue<ShadowAssociationType> cval : objectWrapper.getAssociations()) { 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 = parent.findReference(ShadowType.F_RESOURCE_REF); PrismObject<ResourceType> resource = resourceRef.getValue().getObject(); // HACK. The revive should not be here. Revive is no good. The next use of the resource will // cause parsing of resource schema. We need some centralized place to maintain live cached // copies // of resources. try { resource.revive(prismContext); } catch (SchemaException e) { throw new SystemException(e.getMessage(), e); } RefinedResourceSchema refinedSchema; CompositeRefinedObjectClassDefinition rOcDef; try { refinedSchema = RefinedResourceSchema.getRefinedSchema(resource); rOcDef = refinedSchema.determineCompositeObjectClassDefinition(parent); } 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.getAssociations()) { QName name = assocDef.getName(); if (!assocMap.containsKey(name)) { PrismContainer<ShadowAssociationType> fractionalContainer = new PrismContainer<>( ShadowType.F_ASSOCIATION, ShadowAssociationType.class, prismContext); fractionalContainer.setDefinition(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 (Entry<QName, PrismContainer<ShadowAssociationType>> assocEntry : assocMap.entrySet()) { // HACK HACK HACK, the container wrapper should not parse itself. This code should not be // here. AssociationWrapper assocWrapper = new AssociationWrapper( this, assocEntry.getValue(), this.isReadonly(), ValueStatus.NOT_CHANGED); properties.add(assocWrapper); } } else { // if not an assignment 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) { if (itemDef instanceof PrismPropertyDefinition) { PrismPropertyDefinition def = (PrismPropertyDefinition) itemDef; if (def.isIgnored() || skipProperty(def)) { continue; } if (!showInheritedObjectAttributes && INHERITED_OBJECT_ATTRIBUTES.contains(def.getName())) { continue; } // capability handling for activation properties if (isShadowActivation() && !hasCapability(def)) { continue; } if (isShadowAssociation()) { continue; } PrismProperty property = container.findProperty(def.getName()); boolean propertyIsReadOnly; // decision is based on parent object status, not this // container's one (because container can be added also // to an existing object) if (objectWrapper.getStatus() == ContainerStatus.MODIFYING) { propertyIsReadOnly = !def.canModify(); } else { propertyIsReadOnly = !def.canAdd(); } if (property == null) { properties.add( new PropertyWrapper( this, def.instantiate(), propertyIsReadOnly, ValueStatus.ADDED)); } else { properties.add( new PropertyWrapper(this, 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; // decision is based on parent object status, not this // container's one (because container can be added also // to an existing object) if (objectWrapper.getStatus() == ContainerStatus.MODIFYING) { propertyIsReadOnly = !def.canModify(); } else { propertyIsReadOnly = !def.canAdd(); } if (reference == null) { properties.add( new ReferenceWrapper( this, def.instantiate(), propertyIsReadOnly, ValueStatus.ADDED)); } else { properties.add( new ReferenceWrapper( this, reference, propertyIsReadOnly, ValueStatus.NOT_CHANGED)); } } } } } Collections.sort(properties, new ItemWrapperComparator()); result.recomputeStatus(); return properties; }