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.defaults; 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 016 import java.util.ArrayList; 017 import java.util.HashSet; 018 import java.util.List; 019 import java.util.Set; 020 021 022 /** 023 * Visitor to verify {@link PicoContainer} instances. The visitor walks down the logical container hierarchy. 024 * 025 * @author Jörg Schaible 026 * @since 1.1 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 }