Coverage Report - org.apache.tapestry5.internal.TapestryAppInitializer
 
Classes in this File Line Coverage Branch Coverage Complexity
TapestryAppInitializer
98%
53/54
83%
10/12
0
 
 1  
 // Copyright 2006, 2007, 2008, 2009 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.internal;
 16  
 
 17  
 import org.apache.tapestry5.SymbolConstants;
 18  
 import org.apache.tapestry5.ioc.IOCUtilities;
 19  
 import org.apache.tapestry5.ioc.Registry;
 20  
 import org.apache.tapestry5.ioc.RegistryBuilder;
 21  
 import org.apache.tapestry5.ioc.def.ContributionDef;
 22  
 import org.apache.tapestry5.ioc.def.ModuleDef;
 23  
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
 24  
 import org.apache.tapestry5.ioc.services.*;
 25  
 import org.apache.tapestry5.services.TapestryModule;
 26  
 import org.slf4j.Logger;
 27  
 
 28  
 import java.util.Formatter;
 29  
 import java.util.List;
 30  
 
 31  
 /**
 32  
  * This class is used to build the {@link Registry}. The Registry contains {@link org.apache.tapestry5.ioc.services.TapestryIOCModule}
 33  
  * and {@link TapestryModule}, any modules identified by {@link #addModules(Class[])} )}, plus the application module.
 34  
  * <p/>
 35  
  * The application module is optional.
 36  
  * <p/>
 37  
  * The application module is identified as <em>package</em>.services.<em>appName</em>Module, where <em>package</em> and
 38  
  * the <em>appName</em> are specified by the caller.
 39  
  */
 40  
 public class TapestryAppInitializer
 41  
 {
 42  
     private final Logger logger;
 43  
 
 44  
     private final SymbolProvider appProvider;
 45  
 
 46  
     private final String appName;
 47  
 
 48  
     private final String aliasMode;
 49  
 
 50  
     private final long startTime;
 51  
 
 52  60
     private final RegistryBuilder builder = new RegistryBuilder();
 53  
 
 54  
     private long registryCreatedTime;
 55  
     private Registry registry;
 56  
 
 57  
     public TapestryAppInitializer(Logger logger, String appPackage, String appName, String aliasMode)
 58  
     {
 59  4
         this(logger, new SingleKeySymbolProvider(InternalConstants.TAPESTRY_APP_PACKAGE_PARAM, appPackage), appName,
 60  
              aliasMode);
 61  4
     }
 62  
 
 63  
     /**
 64  
      * @param logger      logger for output confirmation
 65  
      * @param appProvider provides symbols for the application (normally, from the ServletContext init parameters)
 66  
      * @param appName     the name of the application (i.e., the name of the application servlet)
 67  
      * @param aliasMode   the mode, used by the {@link org.apache.tapestry5.services.Alias} service, normally "servlet"
 68  
      */
 69  
     public TapestryAppInitializer(Logger logger, SymbolProvider appProvider, String appName, String aliasMode)
 70  60
     {
 71  60
         this.logger = logger;
 72  60
         this.appProvider = appProvider;
 73  
 
 74  60
         String appPackage = appProvider.valueForSymbol(InternalConstants.TAPESTRY_APP_PACKAGE_PARAM);
 75  
 
 76  
 
 77  60
         this.appName = appName;
 78  60
         this.aliasMode = aliasMode;
 79  
 
 80  60
         startTime = System.currentTimeMillis();
 81  
 
 82  
 
 83  60
         if (!Boolean.parseBoolean(appProvider.valueForSymbol(InternalConstants.DISABLE_DEFAULT_MODULES_PARAM)))
 84  
         {
 85  60
             IOCUtilities.addDefaultModules(builder);
 86  
         }
 87  
 
 88  
         // This gets added automatically.
 89  
 
 90  60
         addModules(TapestryModule.class);
 91  
 
 92  60
         String className = appPackage + ".services." + InternalUtils.capitalize(this.appName) + "Module";
 93  
 
 94  
         try
 95  
         {
 96  
             // This class is possibly loaded by a parent class loader of the application class
 97  
             // loader. The context class loader should have the approprite view to the module class,
 98  
             // if any.
 99  
 
 100  60
             Class moduleClass = Thread.currentThread().getContextClassLoader().loadClass(className);
 101  
 
 102  58
             builder.add(moduleClass);
 103  
         }
 104  2
         catch (ClassNotFoundException ex)
 105  
         {
 106  
             // That's OK, not all applications will have a module class, even though any
 107  
             // non-trivial application will.
 108  58
         }
 109  
 
 110  
         // Add a synthetic module that contributes symbol sources.
 111  
 
 112  60
         addSyntheticSymbolSourceModule(appPackage);
 113  60
     }
 114  
 
 115  
     /**
 116  
      * Adds additional modules.
 117  
      *
 118  
      * @param moduleDefs
 119  
      */
 120  
     public void addModules(ModuleDef... moduleDefs)
 121  
     {
 122  56
         for (ModuleDef def : moduleDefs)
 123  0
             builder.add(def);
 124  56
     }
 125  
 
 126  
     public void addModules(Class... moduleClasses)
 127  
     {
 128  152
         builder.add(moduleClasses);
 129  152
     }
 130  
 
 131  
     private void addSyntheticSymbolSourceModule(String appPackage)
 132  
     {
 133  60
         ContributionDef appPathContribution =
 134  
                 new SyntheticSymbolSourceContributionDef("AppPath",
 135  
                                                          new SingleKeySymbolProvider(
 136  
                                                                  InternalSymbols.APP_PACKAGE_PATH,
 137  
                                                                  appPackage.replace('.', '/')));
 138  
 
 139  60
         ContributionDef symbolSourceContribution =
 140  
                 new SyntheticSymbolSourceContributionDef("ServletContext",
 141  
                                                          appProvider,
 142  
                                                          "before:ApplicationDefaults");
 143  
 
 144  60
         ContributionDef aliasModeContribution =
 145  
                 new SyntheticSymbolSourceContributionDef("AliasMode",
 146  
                                                          new SingleKeySymbolProvider(InternalSymbols.ALIAS_MODE,
 147  
                                                                                      aliasMode),
 148  
                                                          "before:ServletContext");
 149  
 
 150  60
         ContributionDef appNameContribution =
 151  
                 new SyntheticSymbolSourceContributionDef("AppName",
 152  
                                                          new SingleKeySymbolProvider(InternalSymbols.APP_NAME, appName),
 153  
                                                          "before:ServletContext");
 154  
 
 155  60
         builder.add(new SyntheticModuleDef(symbolSourceContribution, aliasModeContribution, appNameContribution,
 156  
                                            appPathContribution));
 157  60
     }
 158  
 
 159  
     public Registry createRegistry()
 160  
     {
 161  60
         registryCreatedTime = System.currentTimeMillis();
 162  
 
 163  60
         registry = builder.build();
 164  
 
 165  60
         return registry;
 166  
     }
 167  
 
 168  
     public void announceStartup()
 169  
     {
 170  10
         long toFinish = System.currentTimeMillis();
 171  
 
 172  10
         SymbolSource source = registry.getService("SymbolSource", SymbolSource.class);
 173  
 
 174  10
         StringBuilder buffer = new StringBuilder("Startup status:\n\n");
 175  10
         Formatter f = new Formatter(buffer);
 176  
 
 177  10
         f.format("Application '%s' (Tapestry version %s).\n\n" +
 178  
                 "Startup time: %,d ms to build IoC Registry, %,d ms overall.\n\n" +
 179  
                 "Startup services status:\n",
 180  
                  appName,
 181  
                  source.valueForSymbol(SymbolConstants.TAPESTRY_VERSION),
 182  
                  registryCreatedTime - startTime, toFinish - startTime);
 183  
 
 184  10
         int unrealized = 0;
 185  
 
 186  10
         ServiceActivityScoreboard scoreboard = registry
 187  
                 .getService(ServiceActivityScoreboard.class);
 188  
 
 189  10
         List<ServiceActivity> serviceActivity = scoreboard.getServiceActivity();
 190  
 
 191  10
         int longest = 0;
 192  
 
 193  
         // One pass to find the longest name, and to count the unrealized services.
 194  
 
 195  10
         for (ServiceActivity activity : serviceActivity)
 196  
         {
 197  1642
             Status status = activity.getStatus();
 198  
 
 199  1642
             longest = Math.max(longest, activity.getServiceId().length());
 200  
 
 201  1642
             if (status == Status.DEFINED || status == Status.VIRTUAL) unrealized++;
 202  1642
         }
 203  
 
 204  10
         String formatString = "%" + longest + "s: %s\n";
 205  
 
 206  
         // A second pass to output all the services
 207  
 
 208  10
         for (ServiceActivity activity : serviceActivity)
 209  
         {
 210  1642
             f.format(formatString, activity.getServiceId(), activity.getStatus().name());
 211  
         }
 212  
 
 213  10
         f.format("\n%4.2f%% unrealized services (%d/%d)\n", 100. * unrealized / serviceActivity.size(), unrealized,
 214  
                  serviceActivity.size());
 215  
 
 216  10
         logger.info(buffer.toString());
 217  10
     }
 218  
 }