Save This Page
Home » tapestry-src-5.0.19 » org.apache.tapestry5.ioc » [javadoc | source]
    1   // Copyright 2006, 2007, 2008 The Apache Software Foundation
    2   //
    3   // Licensed under the Apache License, Version 2.0 (the "License");
    4   // you may not use this file except in compliance with the License.
    5   // You may obtain a copy of the License at
    6   //
    7   //     http://www.apache.org/licenses/LICENSE-2.0
    8   //
    9   // Unless required by applicable law or agreed to in writing, software
   10   // distributed under the License is distributed on an "AS IS" BASIS,
   11   // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   12   // See the License for the specific language governing permissions and
   13   // limitations under the License.
   14   
   15   package org.apache.tapestry5.ioc;
   16   
   17   import org.apache.tapestry5.ioc.annotations.SubModule;
   18   import org.apache.tapestry5.ioc.def.ModuleDef;
   19   import org.apache.tapestry5.ioc.internal.DefaultModuleDefImpl;
   20   import org.apache.tapestry5.ioc.internal.LoggerSourceImpl;
   21   import org.apache.tapestry5.ioc.internal.RegistryImpl;
   22   import org.apache.tapestry5.ioc.internal.RegistryWrapper;
   23   import org.apache.tapestry5.ioc.internal.services.ClassFactoryImpl;
   24   import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
   25   import org.apache.tapestry5.ioc.internal.util.InternalUtils;
   26   import org.apache.tapestry5.ioc.internal.util.OneShotLock;
   27   import org.apache.tapestry5.ioc.services.ClassFactory;
   28   import org.apache.tapestry5.ioc.services.TapestryIOCModule;
   29   import org.slf4j.Logger;
   30   
   31   import java.lang.reflect.AnnotatedElement;
   32   import java.util.Arrays;
   33   import java.util.List;
   34   import java.util.Set;
   35   
   36   /**
   37    * Used to construct the IoC {@link org.apache.tapestry5.ioc.Registry}. This class is <em>not</em> thread-safe. The
   38    * Registry, once created, <em>is</em> thread-safe.
   39    */
   40   public final class RegistryBuilder
   41   {
   42       private final OneShotLock lock = new OneShotLock();
   43   
   44       /**
   45        * Module defs, keyed on module id.
   46        */
   47       final List<ModuleDef> modules = CollectionFactory.newList();
   48   
   49       private final ClassLoader classLoader;
   50   
   51       private final Logger logger;
   52   
   53       private final LoggerSource loggerSource;
   54   
   55       private final ClassFactory classFactory;
   56   
   57       private final Set<Class> addedModuleClasses = CollectionFactory.newSet();
   58   
   59       public RegistryBuilder()
   60       {
   61           this(Thread.currentThread().getContextClassLoader());
   62       }
   63   
   64       public RegistryBuilder(ClassLoader classLoader)
   65       {
   66           this(classLoader, new LoggerSourceImpl());
   67       }
   68   
   69       public RegistryBuilder(ClassLoader classLoader, LoggerSource loggerSource)
   70       {
   71           this.classLoader = classLoader;
   72           this.loggerSource = loggerSource;
   73           logger = loggerSource.getLogger(RegistryBuilder.class);
   74   
   75           // Make the ClassFactory appear to be a service inside TapestryIOCModule, even before that
   76           // module exists.
   77   
   78           Logger classFactoryLogger = loggerSource.getLogger(TapestryIOCModule.class.getName() + ".ClassFactory");
   79   
   80           classFactory = new ClassFactoryImpl(this.classLoader, classFactoryLogger);
   81   
   82           add(TapestryIOCModule.class);
   83       }
   84   
   85       /**
   86        * Adds a {@link ModuleDef} to the registry, returning the builder for further configuration.
   87        */
   88       public RegistryBuilder add(ModuleDef moduleDef)
   89       {
   90           lock.check();
   91   
   92           // TODO: Some way to ensure that duplicate modules are not being added.
   93           // Part of TAPESTRY-2117 is in add(Class...) and that may be as much as we can
   94           // do as there is no concept of ModuleDef identity.
   95   
   96           modules.add(moduleDef);
   97   
   98           return this;
   99       }
  100   
  101       /**
  102        * Adds a number of modules (as module classes) to the registry, returning the builder for further configuration.
  103        *
  104        * @see org.apache.tapestry5.ioc.annotations.SubModule
  105        */
  106       public RegistryBuilder add(Class... moduleBuilderClasses)
  107       {
  108           lock.check();
  109   
  110           List<Class> queue = CollectionFactory.newList(Arrays.asList(moduleBuilderClasses));
  111   
  112           while (!queue.isEmpty())
  113           {
  114               Class c = queue.remove(0);
  115   
  116               // Quietly ignore previously added classes.
  117   
  118               if (addedModuleClasses.contains(c)) continue;
  119   
  120               addedModuleClasses.add(c);
  121   
  122               ModuleDef def = new DefaultModuleDefImpl(c, logger, classFactory);
  123               add(def);
  124   
  125               SubModule annotation = ((AnnotatedElement) c).getAnnotation(SubModule.class);
  126   
  127               if (annotation == null) continue;
  128   
  129               queue.addAll(Arrays.asList(annotation.value()));
  130           }
  131   
  132           return this;
  133       }
  134   
  135       /**
  136        * Adds a number of module classes (specified by fully qualified class name) to the registry, returning the builder
  137        * for further configuration.
  138        *
  139        * @see org.apache.tapestry5.ioc.annotations.SubModule
  140        */
  141       public RegistryBuilder add(String classname)
  142       {
  143           lock.check();
  144   
  145           try
  146           {
  147               Class builderClass = Class.forName(classname, true, classLoader);
  148   
  149               add(builderClass);
  150           }
  151           catch (Exception ex)
  152           {
  153               throw new RuntimeException(String.format("Failure loading Tapestry IoC module class %s: %s",
  154                                                        classname, InternalUtils.toMessage(ex), ex));
  155           }
  156   
  157           return this;
  158       }
  159   
  160       /**
  161        * Constructs and returns the registry; this may only be done once. The caller is responsible for invoking {@link
  162        * org.apache.tapestry5.ioc.Registry#performRegistryStartup()}.
  163        */
  164       public Registry build()
  165       {
  166           lock.lock();
  167   
  168           RegistryImpl registry = new RegistryImpl(modules, classFactory, loggerSource);
  169   
  170           return new RegistryWrapper(registry);
  171       }
  172   
  173       public ClassLoader getClassLoader()
  174       {
  175           return classLoader;
  176       }
  177   
  178       public Logger getLogger()
  179       {
  180           return logger;
  181       }
  182   }

Save This Page
Home » tapestry-src-5.0.19 » org.apache.tapestry5.ioc » [javadoc | source]