public static <T> Set<T> getRealValuesOfCollection(Collection<? extends PrismValue> collection) { Set<T> retval = new HashSet<>(collection.size()); for (PrismValue value : collection) { retval.add(value.getRealValue()); } return retval; }
public static <X extends PrismValue> Collection<X> cloneValues(Collection<X> values) { Collection<X> clonedCollection = new ArrayList<>(values.size()); for (X val: values) { clonedCollection.add((X) val.clone()); } return clonedCollection; }
public static <V extends PrismValue> boolean contains(Collection<V> thisSet, V otherValue, EquivalenceStrategy strategy) { for (V thisValue: thisSet) { if (thisValue.equals(otherValue, strategy)) { return true; } } return false; }
private Collection<V> cloneSet(ItemDeltaImpl clone, Collection<V> thisSet) { if (thisSet == null) { return null; } Collection<V> clonedSet = newValueCollection(); for (V thisVal : thisSet) { V clonedVal = (V) thisVal.clone(); clonedVal.setParent(clone); clonedSet.add(clonedVal); } return clonedSet; }
private boolean equivalentSetRealValue(Collection<V> thisValue, Collection<V> otherValues, boolean isDelete) { return MiscUtil.unorderedCollectionEquals(thisValue, otherValues, (v1, v2) -> { if (v1 != null && v2 != null) { if (!isDelete || !(v1 instanceof PrismContainerValue) || !(v2 instanceof PrismContainerValue)) { // Here it is questionable if we should consider adding "assignment id=1 (A)" and "assignment id=2 (A)" // - i.e. assignments with the same real value but different identifiers - the same delta. // Historically, we considered it as such. But the question is if it's correct. return v1.equals(v2, EquivalenceStrategy.REAL_VALUE); } else { // But for container values to be deleted, they can be referred to either using IDs or values. // If content is used - but no IDs - the content must be equal. // If IDs are used - and are the same - the content is irrelevant. // The problem is if one side has content with ID, and the other has the same content without ID. // This might have the same or different effect, depending on the content it is applied to. // See MID-3828 return v1.equals(v2, EquivalenceStrategy.REAL_VALUE_CONSIDER_DIFFERENT_IDS) || v1.representsSameValue(v2, false); } } else { return false; } }); }
public boolean remove(V newValue) { checkMutability(); boolean changed = false; Iterator<V> iterator = values.iterator(); while (iterator.hasNext()) { V val = iterator.next(); // the same algorithm as when deleting the item value from delete delta if (val.representsSameValue(newValue, false) || val.equals(newValue, EquivalenceStrategy.REAL_VALUE_CONSIDER_DIFFERENT_IDS)) { iterator.remove(); val.setParent(null); changed = true; } } return changed; }
private void handleBasicOrEmbedded(Object bean, ItemDelta delta, Attribute attribute) { Class outputType = getRealOutputType(attribute); PrismValue anyPrismValue = delta.getAnyValue(); Object value; if (delta.isDelete() || (delta.isReplace() && (anyPrismValue == null || anyPrismValue.isEmpty()))) { value = null; } else { value = anyPrismValue.getRealValue(); } value = prismEntityMapper.map(value, outputType); try { PropertyUtils.setSimpleProperty(bean, attribute.getName(), value); } catch (Exception ex) { throw new SystemException("Couldn't set simple property for '" + attribute.getName() + "'", ex); } }
public boolean add(@NotNull V newValue, boolean checkUniqueness, @NotNull EquivalenceStrategy equivalenceStrategy) throws SchemaException { checkMutability(); if (newValue.getPrismContext() == null) { newValue.setPrismContext(prismContext); } Itemable originalParent = newValue.getParent(); newValue.setParent(this); // needed e.g. because of PrismReferenceValue comparisons if (checkUniqueness && contains(newValue, equivalenceStrategy)) { newValue.setParent(originalParent); return false; } D definition = getDefinition(); if (definition != null) { if (!values.isEmpty() && definition.isSingleValue()) { throw new SchemaException("Attempt to put more than one value to single-valued item " + this + "; newly added value: " + newValue); } newValue.applyDefinition(definition, false); } return values.add(newValue); }
private Boolean isRawSet(Collection<V> set) { if (set == null) { return null; } for (V val: set) { if (!val.isRaw()) { return false; } } return true; }
public void checkConsistenceInternal(Itemable rootItem, boolean requireDefinitions, boolean prohibitRaw, ConsistencyCheckScope scope) { ItemPath path = getPath(); if (elementName == null) { throw new IllegalStateException("Item "+this+" has no name ("+path+" in "+rootItem+")"); } if (definition != null) { checkDefinition(definition); } else if (requireDefinitions && !isRaw()) { throw new IllegalStateException("No definition in item "+this+" ("+path+" in "+rootItem+")"); } for (V val: values) { if (prohibitRaw && val.isRaw()) { throw new IllegalStateException("Raw value "+val+" in item "+this+" ("+path+" in "+rootItem+")"); } if (val == null) { throw new IllegalStateException("Null value in item "+this+" ("+path+" in "+rootItem+")"); } if (val.getParent() == null) { throw new IllegalStateException("Null parent for value "+val+" in item "+this+" ("+path+" in "+rootItem+")"); } if (val.getParent() != this) { throw new IllegalStateException("Wrong parent for value "+val+" in item "+this+" ("+path+" in "+rootItem+"), "+ "bad parent: " + val.getParent()); } val.checkConsistenceInternal(rootItem, requireDefinitions, prohibitRaw, scope); } }
protected void process(String desc, ParsingFunction<T> parser, SerializingFunction<T> serializer, String serId) throws Exception { PrismContext prismContext = getPrismContext(); System.out.println("================== Starting test for '" + desc + "' (serializer: " + serId + ") =================="); T value = parser.apply(prismContext.parserFor(getFile())); assertResolvableRawValues(value); // should be right here, before any getValue is called (TODO reconsider) System.out.println("Parsed value: " + desc); System.out.println(value.debugDump()); assertPrismValue(value); if (serializer != null) { String serialized = serializer.apply(value); System.out.println("Serialized:\n" + serialized); T reparsed = parser.apply(prismContext.parserFor(serialized)); assertResolvableRawValues(reparsed); // should be right here, before any getValue is called (TODO reconsider) System.out.println("Reparsed: " + desc); System.out.println(reparsed.debugDump()); assertPrismValue(reparsed); Collection<? extends ItemDelta> deltas = value.diff(reparsed); assertTrue("Deltas not empty", deltas.isEmpty()); assertTrue("Values not equal", value.equals(reparsed, EquivalenceStrategy.NOT_LITERAL)); } }
public void checkConsistence() { Visitor visitor = visitable -> { if (visitable instanceof PrismValue) { if (((PrismValue)visitable).isEmpty()) { throw new IllegalStateException("Empty value "+visitable+" in triple "+PrismValueDeltaSetTripleImpl.this); } } }; accept(visitor); Processor<V> processor = pval -> { if (pval.getParent() != null) { throw new IllegalStateException("Value "+pval+" in triple "+PrismValueDeltaSetTripleImpl.this+" has parent, looks like it was not cloned properly"); } }; foreach(processor); }
if (!pval.isImmutable()) { PrismValue clone = pval.clone(); clone.setImmutable(true); return (T) clone; } else {
private void acceptSet(Collection<V> set, Visitor visitor) { if (set == null) { return; } for (V val: set) { val.accept(visitor); } }
protected void dumpValues(StringBuilder sb, String label, Collection<V> values, int indent) { DebugUtil.indentDebugDump(sb, indent); sb.append(label).append(": "); if (values == null) { sb.append("(null)"); } else { if (DebugUtil.isDetailedDebugDump()) { for (V value: values) { sb.append("\n"); sb.append(value.debugDump(indent + 1)); } } else { Iterator<V> i = values.iterator(); while (i.hasNext()) { V value = i.next(); sb.append(value.toHumanReadableString()); if (i.hasNext()) { sb.append(", "); } } } } }
if (info.itemDefinition == null && value.getParent() != null) { info.itemDefinition = itemDefinition = value.getParent().getDefinition(); if (info.itemDefinition == null) { info.itemDefinition = schemaRegistry.findItemDefinitionByElementName(value.getParent().getElementName()); Class<?> realClass = value.getRealClass(); if (realClass != null) { List<ItemDefinition> definitions = schemaRegistry.findItemDefinitionsByCompileTimeClass(realClass, ItemDefinition.class); if (info.itemName == null && value.getParent() != null) { info.itemName = value.getParent().getElementName(); info.typeName = itemDefinition.getTypeName(); } else { Class<?> realClass = value.getRealClass(); if (realClass != null) { info.typeName = schemaRegistry.determineTypeForClass(realClass);
for (PrismValue prismValue : itemDelta.getValuesToAdd()) { body.append(" --- ADD: "); body.append(prismValue.debugDump(2)); body.append("\n"); for (PrismValue prismValue : itemDelta.getValuesToDelete()) { body.append(" --- DELETE: "); body.append(prismValue.debugDump(2)); body.append("\n"); for (PrismValue prismValue : itemDelta.getValuesToReplace()) { body.append(" --- REPLACE: "); body.append(prismValue.debugDump(2)); body.append("\n");
private void assertSetConsistence(Collection<V> values, String type, boolean requireDefinitions, boolean prohibitRaw, ConsistencyCheckScope scope) { if (values == null) { return; } // This may be not be 100% correct but we can tolerate it now // if (values.isEmpty()) { // throw new // IllegalStateException("The "+type+" values set in "+this+" is not-null but it is empty"); // } for (V val : values) { if (scope.isThorough()) { if (val == null) { throw new IllegalStateException("Null value in the " + type + " values set in " + this); } if (val.getParent() != this) { throw new IllegalStateException("Wrong parent for " + val + " in " + type + " values set in " + this + ": " + val.getParent()); } } val.checkConsistenceInternal(this, requireDefinitions, prohibitRaw, scope); } }