/** Maps an abstract representation of a violation into the appropriate EditorDelegate. */ public static void pushViolations( Iterable<SimpleViolation> violations, EditorDriver<?> driver, KeyMethod keyMethod) { if (violations == null) { return; } DelegateMap delegateMap = DelegateMap.of(driver, keyMethod); // For each violation for (SimpleViolation error : violations) { Object key = error.getKey(); List<AbstractEditorDelegate<?, ?>> delegateList = delegateMap.get(key); if (delegateList != null) { // For each delegate editing some record... for (AbstractEditorDelegate<?, ?> baseDelegate : delegateList) { // compute its base path in the hierarchy... String basePath = baseDelegate.getPath(); // and the absolute path of the leaf editor receiving the error. String absolutePath = (basePath.length() > 0 ? basePath + "." : "") + error.getPath(); final String originalAbsolutePath = absolutePath; while (true) { if (processLeafDelegates(delegateMap, originalAbsolutePath, absolutePath, error)) { break; } else if (processEditors(delegateMap, baseDelegate, absolutePath, error)) { break; } else { // This is guaranteed to never happen because we should always // process a delegate/editor if the absolutePath is empty. // Still, we have the check here to prevent an infinite // loop if something goes wrong. if (absolutePath.isEmpty()) { throw new IllegalStateException("No editor: " + originalAbsolutePath); } absolutePath = getParentPath(absolutePath); } } } } } }
/** * Records an error in any delegates that match the {@code absolutePath}, returning true if any * matched. ({@code originalAbsolutePath} is not used for finding delegates, but is instead used * to determine how to record the error.) */ private static boolean processLeafDelegates( DelegateMap delegateMap, String originalAbsolutePath, String absolutePath, SimpleViolation error) { // Find the leaf editor's delegate. List<AbstractEditorDelegate<?, ?>> leafDelegates = delegateMap.getDelegatesByPath(absolutePath); if (leafDelegates == null) { return false; } String addlPath = originalAbsolutePath.substring(absolutePath.length()); for (AbstractEditorDelegate<?, ?> delegate : leafDelegates) { // If this is the original path value, don't record the additional path. if (addlPath.isEmpty()) { delegate.recordError(error.getMessage(), null, error.getUserDataObject()); } else { // Otherwise, include the additional path. delegate.recordError( error.getMessage(), null, error.getUserDataObject(), addlPath, delegate.getEditor()); } } return true; }
/** Records an error in any editors that match the path, returning true if any editors matched. */ private static boolean processEditors( DelegateMap delegateMap, AbstractEditorDelegate<?, ?> baseDelegate, String absolutePath, SimpleViolation error) { List<Editor<?>> editors = delegateMap.getEditorByPath(absolutePath); if (editors == null) { return false; } // No EditorDelegate to attach it to, so record on the baseDelegate // with the appropriate editor & path. for (Editor<?> editor : editors) { baseDelegate.recordError( error.getMessage(), null, error.getUserDataObject(), error.getPath(), editor); } return true; }