/** * Invoked when a source metadata element is about to be written in an existing target element. * The default implementation returns {@link Resolution#MERGE} if writing in the given target * would only fill holes, without overwriting any existing value. Otherwise this method returns * {@code Resolution#SEPARATE}. * * @param source the source metadata to copy. * @param target where the source metadata would be copied if this method returns {@link Resolution#MERGE}. * @return {@link Resolution#MERGE} for writing {@code source} into {@code target}, or * {@link Resolution#SEPARATE} for writing {@code source} in a separated metadata element, or * {@link Resolution#IGNORE} for discarding {@code source}. */ protected Resolution resolve(Object source, ModifiableMetadata target) { return copy(source, target, true) ? Resolution.MERGE : Resolution.SEPARATE; }
/** * Invoked when {@code Merger} can not merge a metadata value by itself. * The default implementation throws an {@link InvalidMetadataException}. * Subclasses can override this method if they want to perform a different processing. * * @param target the metadata instance in which the value should have been written. * @param propertyName the name of the property to write. * @param sourceValue the value to write. * @param targetValue the value that already exist in the target metadata. */ protected void merge(ModifiableMetadata target, String propertyName, Object sourceValue, Object targetValue) { throw new InvalidMetadataException(errors().getString(Errors.Keys.ValueAlreadyDefined_1, name(target, propertyName))); } }
throw new IllegalArgumentException(errors().getString(Errors.Keys.CrossReferencesNotSupported)); if (targetValue != null) { if (targetValue instanceof ModifiableMetadata) { success = copy(sourceValue, (ModifiableMetadata) targetValue, dryRun); if (!success) { throw new InvalidMetadataException(errors().getString(Errors.Keys.IllegalPropertyValueClass_3, name(target, propertyName), ((ModifiableMetadata) targetValue).getInterface(), Classes.getClass(sourceValue))); distribute: while (it.hasNext()) { final Object value = it.next(); switch (resolve(value, (ModifiableMetadata) element)) { if (!copy(value, (ModifiableMetadata) element, false)) break; throw new InvalidMetadataException(errors().getString( Errors.Keys.UnsupportedImplementation_1, Classes.getShortClassName(targetList))); if (!success) { if (dryRun) break; merge(target, propertyName, sourceValue, targetValue); success = true; // If no exception has been thrown by 'merged', assume the conflict solved.
/** * Merges the data from the given source into the given target. * See class javadoc for a description of the merge process. * * @param source the source metadata to merge into the target. Will never be modified. * @param target the target metadata where to merge values. Will be modified as a result of this call. * @throws ClassCastException if the source and target are not instances of the same metadata standard. * @throws InvalidMetadataException if the {@code target} metadata can not hold all {@code source} properties, * for example because the source class is a more specialized type than the target class. * @throws IllegalArgumentException if this method detects a cross-reference between source and target metadata. */ public final void copy(final Object source, final ModifiableMetadata target) { if (!copy(source, target, false)) { throw new InvalidMetadataException(errors().getString(Errors.Keys.IllegalArgumentClass_3, "target", target.getStandard().getInterface(source.getClass()), Classes.getClass(target))); } }
throw new IllegalArgumentException(errors().getString(Errors.Keys.CrossReferencesNotSupported)); if (targetValue != null) { if (targetValue instanceof ModifiableMetadata) { success = copy(sourceValue, (ModifiableMetadata) targetValue, dryRun); if (!success) { throw new InvalidMetadataException(errors().getString(Errors.Keys.IllegalPropertyValueClass_3, name(target, propertyName), ((ModifiableMetadata) targetValue).getInterface(), Classes.getClass(sourceValue))); distribute: while (it.hasNext()) { final Object value = it.next(); switch (resolve(value, (ModifiableMetadata) element)) { if (!copy(value, (ModifiableMetadata) element, false)) break; throw new InvalidMetadataException(errors().getString( Errors.Keys.UnsupportedImplementation_1, Classes.getShortClassName(targetList))); if (!success) { if (dryRun) break; merge(target, propertyName, sourceValue, targetValue); success = true; // If no exception has been thrown by 'merged', assume the conflict solved.
/** * Merges the data from the given source into the given target. * See class javadoc for a description of the merge process. * * @param source the source metadata to merge into the target. Will never be modified. * @param target the target metadata where to merge values. Will be modified as a result of this call. * @throws ClassCastException if the source and target are not instances of the same metadata standard. * @throws InvalidMetadataException if the {@code target} metadata can not hold all {@code source} properties, * for example because the source class is a more specialized type than the target class. * @throws IllegalArgumentException if this method detects a cross-reference between source and target metadata. */ public final void copy(final Object source, final ModifiableMetadata target) { if (!copy(source, target, false)) { throw new InvalidMetadataException(errors().getString(Errors.Keys.IllegalArgumentClass_3, "target", target.getStandard().getInterface(source.getClass()), Classes.getClass(target))); } }
/** * Invoked when {@code Merger} can not merge a metadata value by itself. * The default implementation throws an {@link InvalidMetadataException}. * Subclasses can override this method if they want to perform a different processing. * * @param target the metadata instance in which the value should have been written. * @param propertyName the name of the property to write. * @param sourceValue the value to write. * @param targetValue the value that already exist in the target metadata. */ protected void merge(ModifiableMetadata target, String propertyName, Object sourceValue, Object targetValue) { throw new InvalidMetadataException(errors().getString(Errors.Keys.ValueAlreadyDefined_1, name(target, propertyName))); } }
/** * Invoked when a source metadata element is about to be written in an existing target element. * The default implementation returns {@link Resolution#MERGE} if writing in the given target * would only fill holes, without overwriting any existing value. Otherwise this method returns * {@code Resolution#SEPARATE}. * * @param source the source metadata to copy. * @param target where the source metadata would be copied if this method returns {@link Resolution#MERGE}. * @return {@link Resolution#MERGE} for writing {@code source} into {@code target}, or * {@link Resolution#SEPARATE} for writing {@code source} in a separated metadata element, or * {@link Resolution#IGNORE} for discarding {@code source}. */ protected Resolution resolve(Object source, ModifiableMetadata target) { return copy(source, target, true) ? Resolution.MERGE : Resolution.SEPARATE; }