001 /*****************************************************************************
002 * Copyright (C) PicoContainer Organization. All rights reserved. *
003 * ------------------------------------------------------------------------- *
004 * The software in this package is published under the terms of the BSD *
005 * style license a copy of which has been included with this distribution in *
006 * the LICENSE.txt file. *
007 *****************************************************************************/
008 package org.picocontainer.visitors;
009
010 import org.picocontainer.ComponentAdapter;
011 import org.picocontainer.Parameter;
012 import org.picocontainer.PicoContainer;
013 import org.picocontainer.PicoVerificationException;
014 import org.picocontainer.PicoVisitor;
015 import org.picocontainer.visitors.TraversalCheckingVisitor;
016
017 import java.util.ArrayList;
018 import java.util.HashSet;
019 import java.util.List;
020 import java.util.Set;
021
022
023 /**
024 * Visitor to verify {@link PicoContainer} instances. The visitor walks down the logical container hierarchy.
025 *
026 * @author Jörg Schaible
027 */
028 public class VerifyingVisitor extends TraversalCheckingVisitor {
029
030 private final List nestedVerificationExceptions;
031 private final Set verifiedComponentAdapters;
032 private final PicoVisitor componentAdapterCollector;
033 private PicoContainer currentPico;
034
035 /**
036 * Construct a VerifyingVisitor.
037 */
038 public VerifyingVisitor() {
039 nestedVerificationExceptions = new ArrayList();
040 verifiedComponentAdapters = new HashSet();
041 componentAdapterCollector = new ComponentAdapterCollector();
042 }
043
044 /**
045 * Traverse through all components of the {@link PicoContainer} hierarchy and verify the components.
046 *
047 * @throws PicoVerificationException if some components could not be verified.
048 * @see org.picocontainer.PicoVisitor#traverse(java.lang.Object)
049 */
050 public Object traverse(Object node) throws PicoVerificationException {
051 nestedVerificationExceptions.clear();
052 verifiedComponentAdapters.clear();
053 try {
054 super.traverse(node);
055 if (!nestedVerificationExceptions.isEmpty()) {
056 throw new PicoVerificationException(new ArrayList(nestedVerificationExceptions));
057 }
058 } finally {
059 nestedVerificationExceptions.clear();
060 verifiedComponentAdapters.clear();
061 }
062 return Void.TYPE;
063 }
064
065 public void visitContainer(PicoContainer pico) {
066 super.visitContainer(pico);
067 currentPico = pico;
068 }
069
070 public void visitComponentAdapter(ComponentAdapter componentAdapter) {
071 super.visitComponentAdapter(componentAdapter);
072 if (!verifiedComponentAdapters.contains(componentAdapter)) {
073 try {
074 componentAdapter.verify(currentPico);
075 } catch (RuntimeException e) {
076 nestedVerificationExceptions.add(e);
077 }
078 componentAdapter.accept(componentAdapterCollector);
079 }
080 }
081
082 private class ComponentAdapterCollector implements PicoVisitor {
083 // /CLOVER:OFF
084 public Object traverse(Object node) {
085 return null;
086 }
087
088 public void visitContainer(PicoContainer pico) {
089 }
090
091 // /CLOVER:ON
092
093 public void visitComponentAdapter(ComponentAdapter componentAdapter) {
094 verifiedComponentAdapters.add(componentAdapter);
095 }
096
097 public void visitParameter(Parameter parameter) {
098 }
099 }
100 }