Coverage Report - org.apache.turbine.services.pull.TurbinePullService
 
Classes in this File Line Coverage Branch Coverage Complexity
TurbinePullService
56%
135/237
44%
39/88
3,478
TurbinePullService$ToolData
100%
5/5
N/A
3,478
 
 1  
 package org.apache.turbine.services.pull;
 2  
 
 3  
 
 4  
 /*
 5  
  * Licensed to the Apache Software Foundation (ASF) under one
 6  
  * or more contributor license agreements.  See the NOTICE file
 7  
  * distributed with this work for additional information
 8  
  * regarding copyright ownership.  The ASF licenses this file
 9  
  * to you under the Apache License, Version 2.0 (the
 10  
  * "License"); you may not use this file except in compliance
 11  
  * with the License.  You may obtain a copy of the License at
 12  
  *
 13  
  *   http://www.apache.org/licenses/LICENSE-2.0
 14  
  *
 15  
  * Unless required by applicable law or agreed to in writing,
 16  
  * software distributed under the License is distributed on an
 17  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 18  
  * KIND, either express or implied.  See the License for the
 19  
  * specific language governing permissions and limitations
 20  
  * under the License.
 21  
  */
 22  
 
 23  
 
 24  
 import java.util.ArrayList;
 25  
 import java.util.Iterator;
 26  
 import java.util.List;
 27  
 
 28  
 import org.apache.commons.configuration.Configuration;
 29  
 import org.apache.commons.logging.Log;
 30  
 import org.apache.commons.logging.LogFactory;
 31  
 import org.apache.fulcrum.pool.PoolService;
 32  
 import org.apache.fulcrum.security.model.turbine.TurbineUserManager;
 33  
 import org.apache.turbine.Turbine;
 34  
 import org.apache.turbine.om.security.User;
 35  
 import org.apache.turbine.pipeline.PipelineData;
 36  
 import org.apache.turbine.services.InitializationException;
 37  
 import org.apache.turbine.services.TurbineBaseService;
 38  
 import org.apache.turbine.services.TurbineServices;
 39  
 import org.apache.turbine.services.velocity.TurbineVelocity;
 40  
 import org.apache.turbine.services.velocity.VelocityService;
 41  
 import org.apache.turbine.util.RunData;
 42  
 import org.apache.velocity.context.Context;
 43  
 
 44  
 /**
 45  
  * This is the concrete implementation of the Turbine
 46  
  * Pull Service.
 47  
  * <p>
 48  
  * These are tools that are placed in the context by the service
 49  
  * These tools will be made available to all your
 50  
  * templates. You list the tools in the following way:
 51  
  * <p>
 52  
  * <pre>
 53  
  * tool.&lt;scope&gt;.&lt;id&gt; = &lt;classname&gt;
 54  
  *
 55  
  * &lt;scope&gt;      is the tool scope: global, request, session,
 56  
  *              authorized or persistent (see below for more details)
 57  
  * &lt;id&gt;         is the name of the tool in the context
 58  
  *
 59  
  * You can configure the tools in this way:
 60  
  * tool.&lt;id&gt;.&lt;parameter&gt; = &lt;value&gt;
 61  
  *
 62  
  * So if you find "global", "request", "session" or "persistent" as second
 63  
  * part, it is a configuration to put a tool into the toolbox, else it is a
 64  
  * tool specific configuration.
 65  
  *
 66  
  * For example:
 67  
  *
 68  
  * tool.global.ui    = org.apache.turbine.util.pull.UIManager
 69  
  * tool.global.mm    = org.apache.turbine.util.pull.MessageManager
 70  
  * tool.request.link = org.apache.turbine.services.pull.tools.TemplateLink
 71  
  * tool.request.page = org.apache.turbine.util.template.TemplatePageAttributes
 72  
  *
 73  
  * Then:
 74  
  *
 75  
  * tool.ui.skin = default
 76  
  *
 77  
  * configures the value of "skin" for the "ui" tool.
 78  
  *
 79  
  * Tools are accessible in all templates by the <id> given
 80  
  * to the tool. So for the above listings the UIManager would
 81  
  * be available as $ui, the MessageManager as $mm, the TemplateLink
 82  
  * as $link and the TemplatePageAttributes as $page.
 83  
  *
 84  
  * You should avoid using tool names called "global", "request",
 85  
  * "session" or "persistent" because of clashes with the possible Scopes.
 86  
  *
 87  
  * Scopes:
 88  
  *
 89  
  *  global:     tool is instantiated once and that instance is available
 90  
  *              to all templates for all requests. Tool must be threadsafe.
 91  
  *
 92  
  *  request:    tool is instantiated once for each request (although the
 93  
  *              PoolService is used to recycle instances). Tool need not
 94  
  *              be threadsafe.
 95  
  *
 96  
  *  session:    tool is instantiated once for each user session, and is
 97  
  *              stored in the session.  These tools do not need to be
 98  
  *              threadsafe.
 99  
  *
 100  
  *  authorized: tool is instantiated once for each user session once the
 101  
  *              user logs in. After this, it is a normal session tool.
 102  
  *
 103  
  *  persistent: tool is instantitated once for each user session once
 104  
  *              the user logs in and is is stored in the user's permanent
 105  
  *              hashtable.
 106  
  *              This means for a logged in user the tool will be persisted
 107  
  *              in the user's objectdata. Tool should be Serializable.  These
 108  
  *              tools do not need to be threadsafe.
 109  
  *              <b>persistent scope tools are deprecated in 2.3</b>
 110  
  *
 111  
  * Defaults: none
 112  
  * </pre>
 113  
  *
 114  
  * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
 115  
  * @author <a href="mailto:sean@informage.net">Sean Legassick</a>
 116  
  * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
 117  
  * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
 118  
  * @author <a href="mailto:peter@courcoux.biz">Peter Courcoux</a>
 119  
  * @version $Id: TurbinePullService.java 1706239 2015-10-01 13:18:35Z tv $
 120  
  */
 121  30
 public class TurbinePullService
 122  
         extends TurbineBaseService
 123  
         implements PullService
 124  
 {
 125  
     /** Logging */
 126  30
     private static Log log = LogFactory.getLog(TurbinePullService.class);
 127  
 
 128  
     /** Reference to the pool service */
 129  30
     private PoolService pool = null;
 130  
 
 131  
     /** Reference to the templating (nee Velocity) service */
 132  30
     private VelocityService velocity = null;
 133  
 
 134  
     /**
 135  
      * This is the container for the global web application
 136  
      * tools that are used in conjunction with the
 137  
      * Turbine Pull Model. All the global tools will be placed
 138  
      * in this Context and be made accessible inside
 139  
      * templates via the tool name specified in the TR.props
 140  
      * file.
 141  
      */
 142  
     private Context globalContext;
 143  
 
 144  
     /**
 145  
      * This inner class is used in the lists below to store the
 146  
      * tool name and class for each of request, session and persistent
 147  
      * tools
 148  
      */
 149  
     private static class ToolData
 150  
     {
 151  
         String toolName;
 152  
         String toolClassName;
 153  
         Class<ApplicationTool> toolClass;
 154  
 
 155  
         public ToolData(String toolName, String toolClassName, Class<ApplicationTool> toolClass)
 156  119
         {
 157  119
             this.toolName = toolName;
 158  119
             this.toolClassName = toolClassName;
 159  119
             this.toolClass = toolClass;
 160  119
         }
 161  
     }
 162  
 
 163  
     /** Internal list of global tools */
 164  
     private List<ToolData> globalTools;
 165  
 
 166  
     /** Internal list of request tools */
 167  
     private List<ToolData> requestTools;
 168  
 
 169  
     /** Internal list of session tools */
 170  
     private List<ToolData> sessionTools;
 171  
 
 172  
     /** Internal list of authorized tools */
 173  
     private List<ToolData> authorizedTools;
 174  
 
 175  
     /** Internal list of persistent tools */
 176  
     private List<ToolData> persistentTools;
 177  
 
 178  
     /** Directory where application tool resources are stored.*/
 179  
     private String resourcesDirectory;
 180  
 
 181  
     /** Should we refresh the application tools on a per request basis? */
 182  30
     private boolean refreshToolsPerRequest = false;
 183  
 
 184  
     /**
 185  
      * Called the first time the Service is used.
 186  
      */
 187  
     @Override
 188  
     public void init()
 189  
         throws InitializationException
 190  
     {
 191  
         try
 192  
         {
 193  37
                     pool = (PoolService)TurbineServices.getInstance().getService(PoolService.ROLE);
 194  
 
 195  37
             if (pool == null)
 196  
             {
 197  0
                 throw new InitializationException("Pull Service requires"
 198  
                     + " configured Pool Service!");
 199  
             }
 200  
 
 201  37
             initPullService();
 202  
             // Make sure to setInit(true) because Tools may
 203  
             // make calls back to the TurbinePull static methods
 204  
             // which causes an init loop.
 205  37
             setInit(true);
 206  
 
 207  
             // Do _NOT_ move this before the setInit(true)
 208  37
             velocity = TurbineVelocity.getService();
 209  
 
 210  26
             if (velocity != null)
 211  
             {
 212  26
                 initPullTools();
 213  
             }
 214  
             else
 215  
             {
 216  0
                 log.info("Velocity Service not configured, skipping pull tools!");
 217  
             }
 218  
         }
 219  11
         catch (Exception e)
 220  
         {
 221  11
             throw new InitializationException(
 222  
                 "TurbinePullService failed to initialize", e);
 223  26
         }
 224  26
     }
 225  
 
 226  
     /**
 227  
      * Initialize the pull service
 228  
      *
 229  
      * @exception Exception A problem happened when starting up
 230  
      */
 231  
     private void initPullService()
 232  
         throws Exception
 233  
     {
 234  
         // This is the per-service configuration, prefixed with services.PullService
 235  37
         Configuration conf = getConfiguration();
 236  
 
 237  
         // Get the resources directory that is specificed
 238  
         // in the TR.props or default to "resources", relative to the webapp.
 239  37
         resourcesDirectory = conf.getString(
 240  
             TOOL_RESOURCES_DIR_KEY,
 241  
             TOOL_RESOURCES_DIR_DEFAULT);
 242  
 
 243  
         // Should we refresh the tool box on a per
 244  
         // request basis.
 245  37
         refreshToolsPerRequest =
 246  
             conf.getBoolean(
 247  
                 TOOLS_PER_REQUEST_REFRESH_KEY,
 248  
                 TOOLS_PER_REQUEST_REFRESH_DEFAULT);
 249  
 
 250  
         // Log the fact that the application tool box will
 251  
         // be refreshed on a per request basis.
 252  37
         if (refreshToolsPerRequest)
 253  
         {
 254  28
             log.info("Pull Model tools will "
 255  
                 + "be refreshed on a per request basis.");
 256  
         }
 257  37
     }
 258  
 
 259  
     /**
 260  
      * Initialize the pull tools. At this point, the
 261  
      * service must be marked as initialized, because the
 262  
      * tools may call the methods of this service via the
 263  
      * static facade class TurbinePull.
 264  
      *
 265  
      * @exception Exception A problem happened when starting up
 266  
      */
 267  
     private void initPullTools()
 268  
         throws Exception
 269  
     {
 270  
         // And for reasons I never really fully understood,
 271  
         // the tools directive is toplevel without the service
 272  
         // prefix. This is brain-damaged but for legacy reasons we
 273  
         // keep this. So this is the global turbine configuration:
 274  26
         Configuration conf = Turbine.getConfiguration();
 275  
 
 276  
         // Grab each list of tools that are to be used (for global scope,
 277  
         // request scope, authorized scope, session scope and persistent
 278  
         // scope tools). They are specified respectively in the TR.props
 279  
         // like this:
 280  
         //
 281  
         // tool.global.ui = org.apache.turbine.util.pull.UIManager
 282  
         // tool.global.mm = org.apache.turbine.util.pull.MessageManager
 283  
         //
 284  
         // tool.request.link = org.apache.turbine.services.pull.tools.TemplateLink
 285  
         //
 286  
         // tool.session.basket = org.sample.util.ShoppingBasket;
 287  
         //
 288  
         // tool.persistent.ui = org.apache.turbine.services.pull.util.PersistentUIManager
 289  
 
 290  26
         log.debug("Global Tools:");
 291  26
         globalTools     = getTools(conf.subset(GLOBAL_TOOL));
 292  26
         log.debug("Request Tools:");
 293  26
         requestTools    = getTools(conf.subset(REQUEST_TOOL));
 294  26
         log.debug("Session Tools:");
 295  26
         sessionTools    = getTools(conf.subset(SESSION_TOOL));
 296  26
         log.debug("Authorized Tools:");
 297  26
         authorizedTools = getTools(conf.subset(AUTHORIZED_TOOL));
 298  26
         log.debug("Persistent Tools:");
 299  26
         persistentTools = getTools(conf.subset(PERSISTENT_TOOL));
 300  
 
 301  
         // Create and populate the global context right now
 302  
 
 303  
         // This is unholy, because it entwines the VelocityService and
 304  
         // the Pull Service even further. However, there isn't much we can
 305  
         // do for the 2.3 release. Expect this to go post-2.3
 306  26
         globalContext = velocity.getNewContext();
 307  
 
 308  26
         populateWithGlobalTools(globalContext);
 309  26
     }
 310  
 
 311  
     /**
 312  
      * Retrieve the tool names and classes for the tools definied
 313  
      * in the configuration file with the prefix given.
 314  
      *
 315  
      * @param toolConfig The part of the configuration describing some tools
 316  
      */
 317  
     @SuppressWarnings("unchecked")
 318  
     private List<ToolData> getTools(Configuration toolConfig)
 319  
     {
 320  130
         List<ToolData> tools = new ArrayList<ToolData>();
 321  
 
 322  
         // There might not be any tools for this prefix
 323  
         // so return an empty list.
 324  130
         if (toolConfig == null)
 325  
         {
 326  0
             return tools;
 327  
         }
 328  
 
 329  130
         for (Iterator<String> it = toolConfig.getKeys(); it.hasNext();)
 330  
         {
 331  119
             String toolName = it.next();
 332  119
             String toolClassName = toolConfig.getString(toolName);
 333  
 
 334  
             try
 335  
             {
 336  
                 // Create an instance of the tool class.
 337  119
                 Class<ApplicationTool> toolClass = (Class<ApplicationTool>) Class.forName(toolClassName);
 338  
 
 339  
                 // Add the tool to the list being built.
 340  119
                 tools.add(new ToolData(toolName, toolClassName, toolClass));
 341  
 
 342  119
                 log.info("Tool " + toolClassName
 343  
                     + " to add to the context as '$" + toolName + "'");
 344  
             }
 345  0
             catch (Exception e)
 346  
             {
 347  0
                 log.error("Cannot instantiate tool class "
 348  
                     + toolClassName + ": ", e);
 349  119
             }
 350  119
         }
 351  
 
 352  130
         return tools;
 353  
     }
 354  
 
 355  
     /**
 356  
      * Return the Context which contains all global tools that
 357  
      * are to be used in conjunction with the Turbine
 358  
      * Pull Model. The tools are refreshed every time the
 359  
      * global Context is pulled.
 360  
      */
 361  
     @Override
 362  
     public Context getGlobalContext()
 363  
     {
 364  10
         if (refreshToolsPerRequest)
 365  
         {
 366  10
             refreshGlobalTools();
 367  
         }
 368  10
         return globalContext;
 369  
     }
 370  
 
 371  
     /**
 372  
      * Populate the given context with all request, session, authorized
 373  
      * and persistent scope tools (it is assumed that the context
 374  
      * already wraps the global context, and thus already contains
 375  
      * the global tools).
 376  
      *
 377  
      * @param context a Velocity Context to populate
 378  
      * @param data a RunData object for request specific data
 379  
      */
 380  
     @Override
 381  
     public void populateContext(Context context, RunData data)
 382  
     {
 383  0
         populateWithRequestTools(context, data);
 384  
 
 385  
         // session tools (whether session-only or persistent are
 386  
         // very similar, so the same method is used - the
 387  
         // boolean parameter indicates whether get/setPerm is to be used
 388  
         // rather than get/setTemp)
 389  
 
 390  
         //
 391  
         // Session Tool start right at the session once the user has been set
 392  
         // while persistent and authorized Tools are started when the user has
 393  
         // logged in
 394  
         //
 395  0
         User user = data.getUser();
 396  
 
 397  
         // Note: Session tools are currently lost after the login action
 398  
         // because the anonymous user is replaced the the real user object.
 399  
         // We should either store the session pull tools in the session or
 400  
         // make Turbine.loginAction() copy the session pull tools into the
 401  
         // new user object.
 402  0
         populateWithSessionTools(sessionTools, context, data, user);
 403  
 
 404  0
         TurbineUserManager userManager =
 405  
                 (TurbineUserManager)TurbineServices
 406  
                         .getInstance()
 407  
                         .getService(TurbineUserManager.ROLE);
 408  
 
 409  0
         if (!userManager.isAnonymousUser(user))
 410  
         {
 411  0
             if (user.hasLoggedIn())
 412  
             {
 413  0
                 populateWithSessionTools(authorizedTools, context, data, user);
 414  0
                 populateWithPermTools(persistentTools, context, data, user);
 415  
             }
 416  
         }
 417  0
     }
 418  
 
 419  
     /**
 420  
      * Populate the given context with all request, session, authorized
 421  
      * and persistent scope tools (it is assumed that the context
 422  
      * already wraps the global context, and thus already contains
 423  
      * the global tools).
 424  
      *
 425  
      * @param context a Velocity Context to populate
 426  
      * @param pipelineData a PipelineData object for request specific data
 427  
      */
 428  
     @Override
 429  
     public void populateContext(Context context, PipelineData pipelineData)
 430  
     {
 431  
        // Map runDataMap = (Map) pipelineData.get(RunData.class);
 432  
        // RunData data = (RunData)runDataMap.get(RunData.class);
 433  9
         RunData data = (RunData)pipelineData;
 434  
 
 435  9
         populateWithRequestTools(context, pipelineData);
 436  
         // session tools (whether session-only or persistent are
 437  
         // very similar, so the same method is used - the
 438  
         // boolean parameter indicates whether get/setPerm is to be used
 439  
         // rather than get/setTemp)
 440  
 
 441  
         //
 442  
         // Session Tool start right at the session once the user has been set
 443  
         // while persistent and authorized Tools are started when the user has
 444  
         // logged in
 445  
         //
 446  9
         User user = data.getUser();
 447  
 
 448  
         // Note: Session tools are currently lost after the login action
 449  
         // because the anonymous user is replaced the the real user object.
 450  
         // We should either store the session pull tools in the session or
 451  
         // make Turbine.loginAction() copy the session pull tools into the
 452  
         // new user object.
 453  9
         populateWithSessionTools(sessionTools, context, pipelineData, user);
 454  
 
 455  9
         TurbineUserManager userManager =
 456  
                 (TurbineUserManager)TurbineServices
 457  
                         .getInstance()
 458  
                         .getService(TurbineUserManager.ROLE);
 459  
 
 460  9
         if (!userManager.isAnonymousUser(user))
 461  
         {
 462  2
             if (user.hasLoggedIn())
 463  
             {
 464  2
                 populateWithSessionTools(authorizedTools, context, pipelineData, user);
 465  2
                 populateWithPermTools(persistentTools, context, pipelineData, user);
 466  
             }
 467  
         }
 468  9
     }
 469  
 
 470  
     /**
 471  
      * Populate the given context with the global tools
 472  
      *
 473  
      * @param context a Velocity Context to populate
 474  
      */
 475  
     private void populateWithGlobalTools(Context context)
 476  
     {
 477  26
         for (Iterator<ToolData> it = globalTools.iterator(); it.hasNext();)
 478  
         {
 479  17
             ToolData toolData = it.next();
 480  
             try
 481  
             {
 482  17
                 Object tool = toolData.toolClass.newInstance();
 483  
 
 484  
                 // global tools are init'd with a null data parameter
 485  17
                 initTool(tool, null);
 486  
 
 487  
                 // put the tool in the context
 488  17
                 context.put(toolData.toolName, tool);
 489  
             }
 490  0
             catch (Exception e)
 491  
             {
 492  0
                 log.error("Could not instantiate global tool "
 493  
                     + toolData.toolName + " from a "
 494  
                     + toolData.toolClassName + " object", e);
 495  17
             }
 496  17
         }
 497  26
     }
 498  
 
 499  
     /**
 500  
      * Populate the given context with the request-scope tools
 501  
      *
 502  
      * @param context a Velocity Context to populate
 503  
      * @param pipelineData a RunData instance
 504  
      */
 505  
     private void populateWithRequestTools(Context context, RunData data)
 506  
     {
 507  
         // Iterate the tools
 508  0
         for (Iterator<ToolData> it = requestTools.iterator(); it.hasNext();)
 509  
         {
 510  0
             ToolData toolData = it.next();
 511  
             try
 512  
             {
 513  
                 // Fetch Object through the Pool.
 514  0
                 Object tool = pool.getInstance(toolData.toolClass);
 515  
 
 516  
                 // request tools are init'd with a RunData object
 517  0
                 initTool(tool, data);
 518  
 
 519  
                 // put the tool in the context
 520  0
                 context.put(toolData.toolName, tool);
 521  
             }
 522  0
             catch (Exception e)
 523  
             {
 524  0
                 log.error("Could not instantiate request tool "
 525  
                     + toolData.toolName + " from a "
 526  
                     + toolData.toolClassName + " object", e);
 527  0
             }
 528  0
         }
 529  0
     }
 530  
 
 531  
 
 532  
     /**
 533  
      * Populate the given context with the request-scope tools
 534  
      *
 535  
      * @param context a Velocity Context to populate
 536  
      * @param pipelineData a RunData instance
 537  
      */
 538  
     private void populateWithRequestTools(Context context, PipelineData pipelineData)
 539  
     {
 540  
         // Iterate the tools
 541  9
         for (Iterator<ToolData> it = requestTools.iterator(); it.hasNext();)
 542  
         {
 543  45
             ToolData toolData = it.next();
 544  
             try
 545  
             {
 546  
                 // Fetch Object through the Pool.
 547  45
                 Object tool = pool.getInstance(toolData.toolClass);
 548  
 
 549  45
                 initTool(tool, pipelineData);
 550  
 
 551  
                 // put the tool in the context
 552  45
                 context.put(toolData.toolName, tool);
 553  
             }
 554  0
             catch (Exception e)
 555  
             {
 556  0
                 log.error("Could not instantiate request tool "
 557  
                     + toolData.toolName + " from a "
 558  
                     + toolData.toolClassName + " object", e);
 559  45
             }
 560  45
         }
 561  9
     }
 562  
 
 563  
     /**
 564  
      * Populate the given context with the session-scoped tools.
 565  
      *
 566  
      * @param tools The list of tools with which to populate the
 567  
      * session.
 568  
      * @param context The context to populate.
 569  
      * @param pipelineData The current RunData object
 570  
      * @param user The <code>User</code> object whose storage to
 571  
      * retrieve the tool from.
 572  
      */
 573  
     private void populateWithSessionTools(List<ToolData> tools, Context context,
 574  
             PipelineData pipelineData, User user)
 575  
     {
 576  
         //Map runDataMap = (Map)pipelineData.get(RunData.class);
 577  
         //RunData data = (RunData) runDataMap.get(RunData.class);
 578  11
         RunData runData = (RunData)pipelineData;
 579  
         // Iterate the tools
 580  11
         for (Iterator<ToolData> it = tools.iterator(); it.hasNext();)
 581  
         {
 582  9
             ToolData toolData = it.next();
 583  
             try
 584  
             {
 585  
                 // ensure that tool is created only once for a user
 586  
                 // by synchronizing against the user object
 587  9
                 synchronized (runData.getSession())
 588  
                 {
 589  
                     // first try and fetch the tool from the user's
 590  
                     // hashtable
 591  9
                     Object tool = runData.getSession().getAttribute(
 592  
                             SESSION_TOOLS_ATTRIBUTE_PREFIX
 593  
                             + toolData.toolClassName);
 594  
 
 595  9
                     if (tool == null)
 596  
                     {
 597  
                         // if not there, an instance must be fetched from
 598  
                         // the pool
 599  9
                         tool = pool.getInstance(toolData.toolClass);
 600  
 
 601  
                         // session tools are init'd with the User object
 602  9
                         initTool(tool, user);
 603  
                     }
 604  
 
 605  
                     // *NOT* else
 606  9
                     if(tool != null)
 607  
                     {
 608  
                         // store the newly created tool in the session
 609  9
                         runData.getSession().setAttribute(
 610  
                                 SESSION_TOOLS_ATTRIBUTE_PREFIX
 611  
                                 + tool.getClass().getName(), tool);
 612  
 
 613  
                         // This is a semantics change. In the old
 614  
                         // Turbine, Session tools were initialized and
 615  
                         // then refreshed every time they were pulled
 616  
                         // into the context if "refreshToolsPerRequest"
 617  
                         // was wanted.
 618  
                         //
 619  
                         // RunDataApplicationTools now have a parameter
 620  
                         // for refresh. If it is not refreshed immediately
 621  
                         // after init(), the parameter value will be undefined
 622  
                         // until the 2nd run. So we refresh all the session
 623  
                         // tools on every run, even if we just init'ed it.
 624  
                         //
 625  
 
 626  9
                         if (refreshToolsPerRequest)
 627  
                         {
 628  9
                             refreshTool(tool, pipelineData);
 629  
                         }
 630  
 
 631  
                         // put the tool in the context
 632  9
                         log.debug("Adding " + tool + " to ctx as "
 633  
                                 + toolData.toolName);
 634  9
                         context.put(toolData.toolName, tool);
 635  
                     }
 636  
                     else
 637  
                     {
 638  0
                         log.info("Tool " + toolData.toolName
 639  
                                 + " was null, skipping it.");
 640  
                     }
 641  9
                 }
 642  
             }
 643  0
             catch (Exception e)
 644  
             {
 645  0
                 log.error("Could not instantiate session tool "
 646  
                     + toolData.toolName + " from a "
 647  
                     + toolData.toolClassName + " object", e);
 648  9
             }
 649  9
         }
 650  11
     }
 651  
 
 652  
     /**
 653  
      * Populate the given context with the session-scoped tools.
 654  
      *
 655  
      * @param tools The list of tools with which to populate the
 656  
      * session.
 657  
      * @param context The context to populate.
 658  
      * @param pipelineData The current RunData object
 659  
      * @param user The <code>User</code> object whose storage to
 660  
      * retrieve the tool from.
 661  
      */
 662  
     private void populateWithSessionTools(List<ToolData> tools, Context context,
 663  
             RunData data, User user)
 664  
     {
 665  
         // Iterate the tools
 666  0
         for (Iterator<ToolData> it = tools.iterator(); it.hasNext();)
 667  
         {
 668  0
             ToolData toolData = it.next();
 669  
             try
 670  
             {
 671  
                 // ensure that tool is created only once for a user
 672  
                 // by synchronizing against the user object
 673  0
                 synchronized (data.getSession())
 674  
                 {
 675  
                     // first try and fetch the tool from the user's
 676  
                     // hashtable
 677  0
                     Object tool = data.getSession().getAttribute(
 678  
                             SESSION_TOOLS_ATTRIBUTE_PREFIX
 679  
                             + toolData.toolClassName);
 680  
 
 681  0
                     if (tool == null)
 682  
                     {
 683  
                         // if not there, an instance must be fetched from
 684  
                         // the pool
 685  0
                         tool = pool.getInstance(toolData.toolClass);
 686  
 
 687  
                         // session tools are init'd with the User object
 688  0
                         initTool(tool, user);
 689  
                     }
 690  
 
 691  
                     // *NOT* else
 692  0
                     if(tool != null)
 693  
                     {
 694  
                         // store the newly created tool in the session
 695  0
                         data.getSession().setAttribute(
 696  
                                 SESSION_TOOLS_ATTRIBUTE_PREFIX
 697  
                                 + tool.getClass().getName(), tool);
 698  
 
 699  
                         // This is a semantics change. In the old
 700  
                         // Turbine, Session tools were initialized and
 701  
                         // then refreshed every time they were pulled
 702  
                         // into the context if "refreshToolsPerRequest"
 703  
                         // was wanted.
 704  
                         //
 705  
                         // RunDataApplicationTools now have a parameter
 706  
                         // for refresh. If it is not refreshed immediately
 707  
                         // after init(), the parameter value will be undefined
 708  
                         // until the 2nd run. So we refresh all the session
 709  
                         // tools on every run, even if we just init'ed it.
 710  
                         //
 711  
 
 712  0
                         if (refreshToolsPerRequest)
 713  
                         {
 714  0
                             refreshTool(tool, data);
 715  
                         }
 716  
 
 717  
                         // put the tool in the context
 718  0
                         log.debug("Adding " + tool + " to ctx as "
 719  
                                 + toolData.toolName);
 720  0
                         context.put(toolData.toolName, tool);
 721  
                     }
 722  
                     else
 723  
                     {
 724  0
                         log.info("Tool " + toolData.toolName
 725  
                                 + " was null, skipping it.");
 726  
                     }
 727  0
                 }
 728  
             }
 729  0
             catch (Exception e)
 730  
             {
 731  0
                 log.error("Could not instantiate session tool "
 732  
                     + toolData.toolName + " from a "
 733  
                     + toolData.toolClassName + " object", e);
 734  0
             }
 735  0
         }
 736  0
     }
 737  
 
 738  
 
 739  
 
 740  
     /**
 741  
      * Populate the given context with the perm-scoped tools.
 742  
      *
 743  
      * @param tools The list of tools with which to populate the
 744  
      * session.
 745  
      * @param context The context to populate.
 746  
      * @param pipelineData The current RunData object
 747  
      * @param user The <code>User</code> object whose storage to
 748  
      * retrieve the tool from.
 749  
      */
 750  
     private void populateWithPermTools(List<ToolData> tools, Context context,
 751  
             PipelineData pipelineData, User user)
 752  
     {
 753  
         // Iterate the tools
 754  2
         for (Iterator<ToolData> it = tools.iterator(); it.hasNext();)
 755  
         {
 756  0
             ToolData toolData = it.next();
 757  
             try
 758  
             {
 759  
                 // ensure that tool is created only once for a user
 760  
                 // by synchronizing against the user object
 761  0
                 synchronized (user)
 762  
                 {
 763  
                     // first try and fetch the tool from the user's
 764  
                     // hashtable
 765  0
                     Object tool = user.getPerm(toolData.toolClassName);
 766  
 
 767  0
                     if (tool == null)
 768  
                     {
 769  
                         // if not there, an instance must be fetched from
 770  
                         // the pool
 771  0
                         tool = pool.getInstance(toolData.toolClass);
 772  
 
 773  
                         // session tools are init'd with the User object
 774  0
                         initTool(tool, user);
 775  
 
 776  
                         // store the newly created tool in the user's hashtable
 777  0
                         user.setPerm(toolData.toolClassName, tool);
 778  
                     }
 779  
 
 780  
                     // *NOT* else
 781  0
                     if(tool != null)
 782  
                     {
 783  
                         // This is a semantics change. In the old
 784  
                         // Turbine, Session tools were initialized and
 785  
                         // then refreshed every time they were pulled
 786  
                         // into the context if "refreshToolsPerRequest"
 787  
                         // was wanted.
 788  
                         //
 789  
                         // RunDataApplicationTools now have a parameter
 790  
                         // for refresh. If it is not refreshed immediately
 791  
                         // after init(), the parameter value will be undefined
 792  
                         // until the 2nd run. So we refresh all the session
 793  
                         // tools on every run, even if we just init'ed it.
 794  
                         //
 795  
 
 796  0
                         if (refreshToolsPerRequest)
 797  
                         {
 798  0
                             refreshTool(tool, pipelineData);
 799  
                         }
 800  
 
 801  
                         // put the tool in the context
 802  0
                         log.debug("Adding " + tool + " to ctx as "
 803  
                                 + toolData.toolName);
 804  0
                         log.warn("Persistent scope tools are deprecated.");
 805  0
                         context.put(toolData.toolName, tool);
 806  
                     }
 807  
                     else
 808  
                     {
 809  0
                         log.info("Tool " + toolData.toolName
 810  
                                 + " was null, skipping it.");
 811  
                     }
 812  0
                 }
 813  
             }
 814  0
             catch (Exception e)
 815  
             {
 816  0
                 log.error("Could not instantiate perm tool "
 817  
                     + toolData.toolName + " from a "
 818  
                     + toolData.toolClassName + " object", e);
 819  0
             }
 820  0
         }
 821  2
     }
 822  
 
 823  
     /**
 824  
      * Populate the given context with the perm-scoped tools.
 825  
      *
 826  
      * @param tools The list of tools with which to populate the
 827  
      * session.
 828  
      * @param context The context to populate.
 829  
      * @param pipelineData The current RunData object
 830  
      * @param user The <code>User</code> object whose storage to
 831  
      * retrieve the tool from.
 832  
      */
 833  
     private void populateWithPermTools(List<ToolData> tools, Context context,
 834  
             RunData data, User user)
 835  
     {
 836  
         // Iterate the tools
 837  0
         for (Iterator<ToolData> it = tools.iterator(); it.hasNext();)
 838  
         {
 839  0
             ToolData toolData = it.next();
 840  
             try
 841  
             {
 842  
                 // ensure that tool is created only once for a user
 843  
                 // by synchronizing against the user object
 844  0
                 synchronized (user)
 845  
                 {
 846  
                     // first try and fetch the tool from the user's
 847  
                     // hashtable
 848  0
                     Object tool = user.getPerm(toolData.toolClassName);
 849  
 
 850  0
                     if (tool == null)
 851  
                     {
 852  
                         // if not there, an instance must be fetched from
 853  
                         // the pool
 854  0
                         tool = pool.getInstance(toolData.toolClass);
 855  
 
 856  
                         // session tools are init'd with the User object
 857  0
                         initTool(tool, user);
 858  
 
 859  
                         // store the newly created tool in the user's hashtable
 860  0
                         user.setPerm(toolData.toolClassName, tool);
 861  
                     }
 862  
 
 863  
                     // *NOT* else
 864  0
                     if(tool != null)
 865  
                     {
 866  
                         // This is a semantics change. In the old
 867  
                         // Turbine, Session tools were initialized and
 868  
                         // then refreshed every time they were pulled
 869  
                         // into the context if "refreshToolsPerRequest"
 870  
                         // was wanted.
 871  
                         //
 872  
                         // RunDataApplicationTools now have a parameter
 873  
                         // for refresh. If it is not refreshed immediately
 874  
                         // after init(), the parameter value will be undefined
 875  
                         // until the 2nd run. So we refresh all the session
 876  
                         // tools on every run, even if we just init'ed it.
 877  
                         //
 878  
 
 879  0
                         if (refreshToolsPerRequest)
 880  
                         {
 881  0
                             refreshTool(tool, data);
 882  
                         }
 883  
 
 884  
                         // put the tool in the context
 885  0
                         log.debug("Adding " + tool + " to ctx as "
 886  
                                 + toolData.toolName);
 887  0
                         log.warn("Persistent scope tools are deprecated.");
 888  0
                         context.put(toolData.toolName, tool);
 889  
                     }
 890  
                     else
 891  
                     {
 892  0
                         log.info("Tool " + toolData.toolName
 893  
                                 + " was null, skipping it.");
 894  
                     }
 895  0
                 }
 896  
             }
 897  0
             catch (Exception e)
 898  
             {
 899  0
                 log.error("Could not instantiate perm tool "
 900  
                     + toolData.toolName + " from a "
 901  
                     + toolData.toolClassName + " object", e);
 902  0
             }
 903  0
         }
 904  0
     }
 905  
 
 906  
 
 907  
 
 908  
     /**
 909  
      * Return the absolute path to the resources directory
 910  
      * used by the application tools.
 911  
      *
 912  
      * @return the absolute path of the resources directory
 913  
      */
 914  
     @Override
 915  
     public String getAbsolutePathToResourcesDirectory()
 916  
     {
 917  0
         return Turbine.getRealPath(resourcesDirectory);
 918  
     }
 919  
 
 920  
     /**
 921  
      * Return the resources directory. This is
 922  
      * relative to the web context.
 923  
      *
 924  
      * @return the relative path of the resources directory
 925  
      */
 926  
     @Override
 927  
     public String getResourcesDirectory()
 928  
     {
 929  17
         return resourcesDirectory;
 930  
     }
 931  
 
 932  
     /**
 933  
      * Refresh the global tools. We can
 934  
      * only refresh those tools that adhere to
 935  
      * ApplicationTool interface because we
 936  
      * know those types of tools have a refresh
 937  
      * method.
 938  
      */
 939  
     private void refreshGlobalTools()
 940  
     {
 941  10
         for (Iterator<ToolData> it = globalTools.iterator(); it.hasNext();)
 942  
         {
 943  10
             ToolData toolData = it.next();
 944  10
             Object tool = globalContext.get(toolData.toolName);
 945  10
             refreshTool(tool, null);
 946  10
         }
 947  10
     }
 948  
 
 949  
     /**
 950  
      * Release the request-scope tool instances in the
 951  
      * given Context back to the pool
 952  
      *
 953  
      * @param context the Velocity Context to release tools from
 954  
      */
 955  
     @Override
 956  
     public void releaseTools(Context context)
 957  
     {
 958  
         // only the request tools can be released - other scoped
 959  
         // tools will have continuing references to them
 960  2
         releaseTools(context, requestTools);
 961  2
     }
 962  
 
 963  
     /**
 964  
      * Release the given list of tools from the context back
 965  
      * to the pool
 966  
      *
 967  
      * @param context the Context containing the tools
 968  
      * @param tools a List of ToolData objects
 969  
      */
 970  
     private void releaseTools(Context context, List<ToolData> tools)
 971  
     {
 972  2
         for (Iterator<ToolData> it = tools.iterator(); it.hasNext();)
 973  
         {
 974  10
             ToolData toolData = it.next();
 975  10
             Object tool = context.remove(toolData.toolName);
 976  
 
 977  10
             if (tool != null)
 978  
             {
 979  10
                 pool.putInstance(tool);
 980  
             }
 981  10
         }
 982  2
     }
 983  
 
 984  
     /**
 985  
      * Initialized a given Tool with the passed init Object
 986  
      *
 987  
      * @param tool A Tool Object
 988  
      * @param param The Init Parameter
 989  
      *
 990  
      * @throws Exception If anything went wrong.
 991  
      */
 992  
     private void initTool(Object tool, Object param)
 993  
         throws Exception
 994  
     {
 995  71
         if (param instanceof PipelineData)
 996  
         {
 997  45
             if (tool instanceof PipelineDataApplicationTool)
 998  
             {
 999  0
                 ((PipelineDataApplicationTool) tool).init(param);
 1000  
             }
 1001  45
             else if (tool instanceof RunDataApplicationTool)
 1002  
             {
 1003  0
                 RunData data = getRunData((PipelineData)param);
 1004  0
                 ((RunDataApplicationTool) tool).init(data);
 1005  0
             }
 1006  45
             else if (tool instanceof ApplicationTool)
 1007  
             {
 1008  45
                 RunData data = getRunData((PipelineData)param);
 1009  45
                 ((ApplicationTool) tool).init(data);
 1010  45
             }
 1011  
         }
 1012  
         else
 1013  
         {
 1014  26
             if (tool instanceof PipelineDataApplicationTool)
 1015  
             {
 1016  0
                 ((PipelineDataApplicationTool) tool).init(param);
 1017  
             }
 1018  26
             else if (tool instanceof RunDataApplicationTool)
 1019  
             {
 1020  0
                 ((RunDataApplicationTool) tool).init(param);
 1021  
             }
 1022  26
             else if (tool instanceof ApplicationTool)
 1023  
             {
 1024  26
                 ((ApplicationTool) tool).init(param);
 1025  
             }
 1026  
         }
 1027  71
     }
 1028  
 
 1029  
     /**
 1030  
      * Refresh a given Tool.
 1031  
      *
 1032  
      * @param tool A Tool Object
 1033  
      * @param pipelineData The current RunData Object
 1034  
      */
 1035  
     private void refreshTool(Object tool, Object dataObject)
 1036  
     {
 1037  19
         RunData data = null;
 1038  19
         PipelineData pipelineData = null;
 1039  19
         if (dataObject instanceof PipelineData)
 1040  
         {
 1041  9
             pipelineData = (PipelineData)dataObject;
 1042  9
             data = getRunData(pipelineData);
 1043  9
             if (tool instanceof PipelineDataApplicationTool)
 1044  
             {
 1045  0
                 ((PipelineDataApplicationTool) tool).refresh(pipelineData);
 1046  
             }
 1047  
         }
 1048  19
         if (tool instanceof ApplicationTool)
 1049  
         {
 1050  19
             ((ApplicationTool) tool).refresh();
 1051  
         }
 1052  0
         else if (tool instanceof RunDataApplicationTool)
 1053  
         {
 1054  0
             ((RunDataApplicationTool) tool).refresh(data);
 1055  
         }
 1056  19
     }
 1057  
 
 1058  
     private RunData getRunData(PipelineData pipelineData)
 1059  
     {
 1060  54
         if(!(pipelineData instanceof RunData)){
 1061  0
             throw new RuntimeException("Can't cast to rundata from pipeline data.");
 1062  
         }
 1063  54
         return (RunData)pipelineData;
 1064  
     }
 1065  
 }