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; }
public static <T> String serializeValue( T value, ItemDefinition def, QName itemName, QName parentName, PrismContext prismContext, String language) throws SchemaException { // System.out.println("value serialization"); if (value == null) { return null; } XNodeSerializer serializer = prismContext.getXnodeProcessor().createSerializer(); if (value instanceof List) { List<T> values = (List<T>) value; if (values.isEmpty()) { return null; } if (def instanceof PrismPropertyDefinition) { PrismProperty prop = (PrismProperty) def.instantiate(itemName); for (T val : values) { PrismPropertyValue<T> pValue = new PrismPropertyValue<T>(val); prop.add(pValue); } XNode node = serializer.serializeItem(prop); if (node instanceof ListXNode) { ListXNode xList = (ListXNode) node; if (xList.size() == 1) { XNode sub = xList.iterator().next(); if (!(sub instanceof MapXNode)) { throw new IllegalArgumentException("must be a map"); } String s = prismContext.getParserDom().serializeToString(sub, parentName); // System.out.println("serialized: " + s); return s; } else { MapXNode xmap = new MapXNode(); xmap.put(itemName, xList); String s = prismContext.getParserDom().serializeToString(xmap, parentName); // System.out.println("serialized: " + s); return s; // throw new IllegalArgumentException("Check your data."); } // MapXNode xmap = xList.new MapXNode(); // xmap.put(def.getName(), xList); } String s = prismContext.getParserDom().serializeToString(node, def.getName()); // System.out.println("serialized: " + s); return s; } else if (def instanceof PrismContainerDefinition) { PrismContainer pc = (PrismContainer) def.instantiate(); for (T val : values) { // PrismContainerValue pcVal = new PrismContainerValue<Containerable>((Containerable) // val); PrismContainerValue pcVal = ((Containerable) val).asPrismContainerValue(); pc.add(pcVal.clone()); } XNode node = serializer.serializeItem(pc); if (node instanceof ListXNode) { ListXNode xList = (ListXNode) node; MapXNode xmap = new MapXNode(); xmap.put(def.getName(), xList); String s = prismContext.getParserDom().serializeToString(xmap, parentName); // System.out.println("serialized: " + s); return s; } String s = prismContext.getParserDom().serializeToString(node, def.getName()); // System.out.println("serialized: " + s); return s; } } PrismValue pVal = null; if (value instanceof Containerable) { pVal = ((Containerable) value).asPrismContainerValue(); } else if (value instanceof Referencable) { pVal = ((Referencable) value).asReferenceValue(); } else { pVal = new PrismPropertyValue<T>(value); } // Class clazz = prismContext.getSchemaRegistry().determineCompileTimeClass(itemName); // PrismContainerDefinition def = // prismContext.getSchemaRegistry().determineDefinitionFromClass(clazz); // // ItemDefinition def = // prismContext.getSchemaRegistry().findItemDefinitionByElementName(itemName); // QName itemName = null; if (def != null) { itemName = def.getName(); } XNode node = serializer.serializeItemValue(pVal, def); String s = prismContext.getParserDom().serializeToString(node, itemName); // System.out.println("serialized: " + s); return s; // throw new UnsupportedOperationException("need to be implemented"); }
private ObjectDelta createAddingObjectDelta() throws SchemaException { PrismObject object = this.object.clone(); List<ContainerWrapper> containers = getContainers(); // sort containers by path size Collections.sort(containers, new PathSizeComparator()); for (ContainerWrapper containerWrapper : getContainers()) { if (containerWrapper.getItemDefinition().getName().equals(ShadowType.F_ASSOCIATION)) { PrismContainer associationContainer = object.findOrCreateContainer(ShadowType.F_ASSOCIATION); List<AssociationWrapper> associationItemWrappers = (List<AssociationWrapper>) containerWrapper.getItems(); for (AssociationWrapper associationItemWrapper : associationItemWrappers) { List<ValueWrapper> assocValueWrappers = associationItemWrapper.getValues(); for (ValueWrapper assocValueWrapper : assocValueWrappers) { PrismContainerValue<ShadowAssociationType> assocValue = (PrismContainerValue<ShadowAssociationType>) assocValueWrapper.getValue(); associationContainer.add(assocValue.clone()); } } continue; } if (!containerWrapper.hasChanged()) { continue; } PrismContainer container = containerWrapper.getItem(); ItemPath path = containerWrapper.getPath(); if (containerWrapper.getPath() != null) { container = container.clone(); if (path.size() > 1) { ItemPath parentPath = path.allExceptLast(); PrismContainer parent = object.findOrCreateContainer(parentPath); parent.add(container); } else { PrismContainer existing = object.findContainer(container.getElementName()); if (existing == null) { object.add(container); } else { continue; } } } else { container = object; } for (ItemWrapper propertyWrapper : (List<ItemWrapper>) containerWrapper.getItems()) { if (!propertyWrapper.hasChanged()) { continue; } Item property = propertyWrapper.getItem().clone(); if (container.findProperty(property.getElementName()) != null) { continue; } for (ValueWrapper valueWrapper : propertyWrapper.getValues()) { valueWrapper.normalize(object.getPrismContext()); if (!valueWrapper.hasValueChanged() || ValueStatus.DELETED.equals(valueWrapper.getStatus())) { continue; } if (property.hasRealValue(valueWrapper.getValue())) { continue; } PrismValue cloned = clone(valueWrapper.getValue()); if (cloned != null) { property.add(cloned); } } if (!property.isEmpty()) { container.add(property); } } } // cleanup empty containers cleanupEmptyContainers(object); ObjectDelta delta = ObjectDelta.createAddDelta(object); // returning container to previous order Collections.sort(containers, new ItemWrapperComparator()); if (InternalsConfig.consistencyChecks) { delta.checkConsistence(true, true, true, ConsistencyCheckScope.THOROUGH); } return delta; }