/* * ============================================================================ * GNU Lesser General Public License * ============================================================================ * * Jargo - JSE Container Toolkit. * Copyright (C) 2006 Leon van Zantvoort * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * * Leon van Zantvoort * 243 Acalanes Drive #11 * Sunnyvale, CA 94086 * USA * * zantvoort@users.sourceforge.net * http://jargo.org */ package org.beanlet.impl; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.beanlet.BeanletApplicationContext; import org.beanlet.BeanletWiringException; import org.beanlet.Dependency; import org.beanlet.IgnoreDependency; import org.beanlet.annotation.AnnotationDomain; import org.beanlet.annotation.Element; import org.beanlet.annotation.ElementAnnotation; import org.beanlet.plugin.BeanletConfiguration; import org.beanlet.common.Beanlets; import org.beanlet.plugin.DependencyInjection; import org.beanlet.plugin.DependencyInjectionFactory; import org.jargo.DependencyInspector; /** * * @author Leon van Zantvoort */ public class DependencyInspectorImpl implements DependencyInspector { private final BeanletConfiguration configuration; private final DependencyInjectionFactory factory; private final ConcurrentMap<Class, Set<String>> cache; public DependencyInspectorImpl(BeanletConfiguration configuration, DependencyInjectionFactory factory) { this.configuration = configuration; this.factory = factory; this.cache = new ConcurrentHashMap<Class, Set<String>>(); } public Set<String> getDependencies(Class<?> cls) { Set<String> dependencies = new HashSet<String>(); if (configuration.getFactory() != null) { dependencies.add(configuration.getFactory()); if (configuration.getFactoryMethod() != null) { BeanletApplicationContext bctx = BeanletApplicationContext.instance(); Class<?> factoryType = bctx.getBeanletFactory( configuration.getFactory()).getBeanletMetaData().getType(); List<DependencyInjection> injections = factory. getFactoryDependencyInjections(factoryType, configuration.getFactoryMethod()); dependencies.addAll(getDependencies(injections)); } } dependencies.addAll(getDependencyDependencies(cls)); dependencies.addAll(getDependencies( factory.getConstructorDependencyInjections(cls))); dependencies.addAll(getDependencies( factory.getSetterDependencyInjections(cls))); return Collections.unmodifiableSet(dependencies); } private Set<String> getDependencies(List<DependencyInjection> injections) { Set<String> dependencies = new HashSet<String>(); for (DependencyInjection injection : injections) { boolean optional = injection.isOptional(); try { for (String dependency : injection.getDependencies()) { if (!optional || BeanletApplicationContext.instance().exists(dependency)) { if (dependency.startsWith(Beanlets.FACTORY_BEANLET_PREFIX)) { dependency = dependency.substring(1); } dependencies.add(dependency); } } } catch (BeanletWiringException e) { if (!optional) { throw e; } } } return dependencies; } private Set<String> getDependencyDependencies(Class<?> cls) { Set<String> dependencies = cache.get(cls); if (dependencies == null) { dependencies = new HashSet<String>(); AnnotationDomain domain = configuration.getAnnotationDomain(); for (ElementAnnotation<Element, Dependency> ea : domain. getDeclaration(Dependency.class).getElements()) { if (ea.getElement().isElementOf(cls)) { if (!domain.getDeclaration(IgnoreDependency.class). isAnnotationPresent(ea.getElement())) { dependencies.addAll(Arrays.asList(ea.getAnnotation().value())); } } } cache.put(cls, dependencies); } return dependencies; } }