##### Coverage Report - org.apache.turbine.services.pull.TurbinePullService

Classes in this File | Line Coverage | Branch Coverage | Complexity
TurbinePullService |
70% | 166/235
53% | 47/88
| 3.4782608695652173;3,478
TurbinePullService$ToolData |
100% | 5/5
N/A | N/A
| 3.4782608695652173;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.turbine.Turbine;
33 |  |
     import org.apache.turbine.om.security.User;
34 |  |
     import org.apache.turbine.pipeline.PipelineData;
35 |  |
     import org.apache.turbine.services.InitializationException;
36 |  |
     import org.apache.turbine.services.TurbineBaseService;
37 |  |
     import org.apache.turbine.services.TurbineServices;
38 |  |
     import org.apache.turbine.services.security.TurbineSecurity;
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 1078552 2011-03-06 19:58:46Z tv $
120 |  |
      */
121 | 58 |
     public class TurbinePullService
122 |  |
             extends TurbineBaseService
123 |  |
             implements PullService
124 |  |
     {
125 |  |
         /** Logging */
126 | 58 |
         private static Log log = LogFactory.getLog(TurbinePullService.class);
127 |  |
128 |  |
         /** Reference to the pool service */
129 | 58 |
         private PoolService pool = null;
130 |  |
131 |  |
         /** Reference to the templating (nee Velocity) service */
132 | 58 |
         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 | 322 |
             {
157 | 322 |
                 this.toolName = toolName;
158 | 322 |
                 this.toolClassName = toolClassName;
159 | 322 |
                 this.toolClass = toolClass;
160 | 322 |
             }
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 | 58 |
         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 | 94 |
                         pool = (PoolService)TurbineServices.getInstance().getService(PoolService.ROLE);
194 |  |
195 | 94 |
                 if (pool == null)
196 |  |
                 {
197 | 0 |
                     throw new InitializationException("Pull Service requires"
198 |  |
                         + " configured Pool Service!");
199 |  |
                 }
200 |  |
201 | 94 |
                 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 | 94 |
                 setInit(true);
206 |  |
207 |  |
                 // Do _NOT_ move this before the setInit(true)
208 | 94 |
                 velocity = TurbineVelocity.getService();
209 |  |
210 | 62 |
                 if (velocity != null)
211 |  |
                 {
212 | 62 |
                     initPullTools();
213 |  |
                 }
214 |  |
                 else
215 |  |
                 {
216 | 0 |
                     log.info("Velocity Service not configured, skipping pull tools!");
217 |  |
                 }
218 |  |
             }
219 | 32 |
             catch (Exception e)
220 |  |
             {
221 | 32 |
                 throw new InitializationException(
222 |  |
                     "TurbinePullService failed to initialize", e);
223 | 62 |
             }
224 | 62 |
         }
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 | 94 |
             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 | 94 |
             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 | 94 |
             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 | 94 |
             if (refreshToolsPerRequest)
253 |  |
             {
254 | 78 |
                 log.info("Pull Model tools will "
255 |  |
                     + "be refreshed on a per request basis.");
256 |  |
             }
257 | 94 |
         }
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 | 62 |
             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 | 62 |
             log.debug("Global Tools:");
291 | 62 |
             globalTools     = getTools(conf.subset(GLOBAL_TOOL));
292 | 62 |
             log.debug("Request Tools:");
293 | 62 |
             requestTools    = getTools(conf.subset(REQUEST_TOOL));
294 | 62 |
             log.debug("Session Tools:");
295 | 62 |
             sessionTools    = getTools(conf.subset(SESSION_TOOL));
296 | 62 |
             log.debug("Authorized Tools:");
297 | 62 |
             authorizedTools = getTools(conf.subset(AUTHORIZED_TOOL));
298 | 62 |
             log.debug("Persistent Tools:");
299 | 62 |
             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 | 62 |
             globalContext = velocity.getNewContext();
307 |  |
308 | 62 |
             populateWithGlobalTools(globalContext);
309 | 62 |
         }
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 | 310 |
             List<ToolData> tools = new ArrayList<ToolData>();
321 |  |
322 |  |
             // There might not be any tools for this prefix
323 |  |
             // so return an empty list.
324 | 310 |
             if (toolConfig == null)
325 |  |
             {
326 | 0 |
                 return tools;
327 |  |
             }
328 |  |
329 | 310 |
             for (Iterator<String> it = toolConfig.getKeys(); it.hasNext();)
330 |  |
             {
331 | 368 |
                 String toolName = it.next();
332 | 368 |
                 String toolClassName = toolConfig.getString(toolName);
333 |  |
334 |  |
                 try
335 |  |
                 {
336 |  |
                     // Create an instance of the tool class.
337 | 368 |
                     Class<ApplicationTool> toolClass = (Class<ApplicationTool>) Class.forName(toolClassName);
338 |  |
339 |  |
                     // Add the tool to the list being built.
340 | 322 |
                     tools.add(new ToolData(toolName, toolClassName, toolClass));
341 |  |
342 | 322 |
                     log.info("Tool " + toolClassName
343 |  |
                         + " to add to the context as '$" + toolName + "'");
344 |  |
                 }
345 | 46 |
                 catch (Exception e)
346 |  |
                 {
347 | 46 |
                     log.error("Cannot instantiate tool class "
348 |  |
                         + toolClassName + ": ", e);
349 | 322 |
                 }
350 | 368 |
             }
351 |  |
352 | 310 |
             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 |  |
         public Context getGlobalContext()
362 |  |
         {
363 | 28 |
             if (refreshToolsPerRequest)
364 |  |
             {
365 | 28 |
                 refreshGlobalTools();
366 |  |
             }
367 | 28 |
             return globalContext;
368 |  |
         }
369 |  |
370 |  |
         /**
371 |  |
          * Populate the given context with all request, session, authorized
372 |  |
          * and persistent scope tools (it is assumed that the context
373 |  |
          * already wraps the global context, and thus already contains
374 |  |
          * the global tools).
375 |  |
          *
376 |  |
          * @param context a Velocity Context to populate
377 |  |
          * @param data a RunData object for request specific data
378 |  |
          */
379 |  |
         public void populateContext(Context context, RunData data)
380 |  |
         {
381 | 10 |
             populateWithRequestTools(context, data);
382 |  |
383 |  |
             // session tools (whether session-only or persistent are
384 |  |
             // very similar, so the same method is used - the
385 |  |
             // boolean parameter indicates whether get/setPerm is to be used
386 |  |
             // rather than get/setTemp)
387 |  |
388 |  |
             //
389 |  |
             // Session Tool start right at the session once the user has been set
390 |  |
             // while persistent and authorized Tools are started when the user has
391 |  |
             // logged in
392 |  |
             //
393 | 10 |
             User user = data.getUser();
394 |  |
395 |  |
             // Note: Session tools are currently lost after the login action
396 |  |
             // because the anonymous user is replaced the the real user object.
397 |  |
             // We should either store the session pull tools in the session or
398 |  |
             // make Turbine.loginAction() copy the session pull tools into the
399 |  |
             // new user object.
400 | 10 |
             populateWithSessionTools(sessionTools, context, data, user);
401 |  |
402 | 10 |
             if (!TurbineSecurity.isAnonymousUser(user))
403 |  |
             {
404 | 0 |
                 if (user.hasLoggedIn())
405 |  |
                 {
406 | 0 |
                     populateWithSessionTools(authorizedTools, context, data, user);
407 | 0 |
                     populateWithPermTools(persistentTools, context, data, user);
408 |  |
                 }
409 |  |
             }
410 | 10 |
         }
411 |  |
412 |  |
         /**
413 |  |
          * Populate the given context with all request, session, authorized
414 |  |
          * and persistent scope tools (it is assumed that the context
415 |  |
          * already wraps the global context, and thus already contains
416 |  |
          * the global tools).
417 |  |
          *
418 |  |
          * @param context a Velocity Context to populate
419 |  |
          * @param data a PipelineData object for request specific data
420 |  |
          */
421 |  |
         public void populateContext(Context context, PipelineData pipelineData)
422 |  |
         {
423 |  |
            // Map runDataMap = (Map) pipelineData.get(RunData.class);
424 |  |
            // RunData data = (RunData)runDataMap.get(RunData.class);
425 | 6 |
             RunData data = (RunData)pipelineData;
426 |  |
427 | 6 |
             populateWithRequestTools(context, pipelineData);
428 |  |
             // session tools (whether session-only or persistent are
429 |  |
             // very similar, so the same method is used - the
430 |  |
             // boolean parameter indicates whether get/setPerm is to be used
431 |  |
             // rather than get/setTemp)
432 |  |
433 |  |
             //
434 |  |
             // Session Tool start right at the session once the user has been set
435 |  |
             // while persistent and authorized Tools are started when the user has
436 |  |
             // logged in
437 |  |
             //
438 | 6 |
             User user = data.getUser();
439 |  |
440 |  |
             // Note: Session tools are currently lost after the login action
441 |  |
             // because the anonymous user is replaced the the real user object.
442 |  |
             // We should either store the session pull tools in the session or
443 |  |
             // make Turbine.loginAction() copy the session pull tools into the
444 |  |
             // new user object.
445 | 6 |
             populateWithSessionTools(sessionTools, context, pipelineData, user);
446 |  |
447 | 6 |
             if (!TurbineSecurity.isAnonymousUser(user))
448 |  |
             {
449 | 2 |
                 if (user.hasLoggedIn())
450 |  |
                 {
451 | 2 |
                     populateWithSessionTools(authorizedTools, context, pipelineData, user);
452 | 2 |
                     populateWithPermTools(persistentTools, context, pipelineData, user);
453 |  |
                 }
454 |  |
             }
455 | 6 |
         }
456 |  |
457 |  |
         /**
458 |  |
          * Populate the given context with the global tools
459 |  |
          *
460 |  |
          * @param context a Velocity Context to populate
461 |  |
          */
462 |  |
         private void populateWithGlobalTools(Context context)
463 |  |
         {
464 | 62 |
             for (Iterator<ToolData> it = globalTools.iterator(); it.hasNext();)
465 |  |
             {
466 | 46 |
                 ToolData toolData = it.next();
467 |  |
                 try
468 |  |
                 {
469 | 46 |
                     Object tool = toolData.toolClass.newInstance();
470 |  |
471 |  |
                     // global tools are init'd with a null data parameter
472 | 46 |
                     initTool(tool, null);
473 |  |
474 |  |
                     // put the tool in the context
475 | 46 |
                     context.put(toolData.toolName, tool);
476 |  |
                 }
477 | 0 |
                 catch (Exception e)
478 |  |
                 {
479 | 0 |
                     log.error("Could not instantiate global tool "
480 |  |
                         + toolData.toolName + " from a "
481 |  |
                         + toolData.toolClassName + " object", e);
482 | 46 |
                 }
483 | 46 |
             }
484 | 62 |
         }
485 |  |
486 |  |
         /**
487 |  |
          * Populate the given context with the request-scope tools
488 |  |
          *
489 |  |
          * @param context a Velocity Context to populate
490 |  |
          * @param data a RunData instance
491 |  |
          */
492 |  |
         private void populateWithRequestTools(Context context, RunData data)
493 |  |
         {
494 |  |
             // Iterate the tools
495 | 10 |
             for (Iterator<ToolData> it = requestTools.iterator(); it.hasNext();)
496 |  |
             {
497 | 50 |
                 ToolData toolData = it.next();
498 |  |
                 try
499 |  |
                 {
500 |  |
                     // Fetch Object through the Pool.
501 | 50 |
                     Object tool = pool.getInstance(toolData.toolClass);
502 |  |
503 |  |
                     // request tools are init'd with a RunData object
504 | 50 |
                     initTool(tool, data);
505 |  |
506 |  |
                     // put the tool in the context
507 | 50 |
                     context.put(toolData.toolName, tool);
508 |  |
                 }
509 | 0 |
                 catch (Exception e)
510 |  |
                 {
511 | 0 |
                     log.error("Could not instantiate request tool "
512 |  |
                         + toolData.toolName + " from a "
513 |  |
                         + toolData.toolClassName + " object", e);
514 | 50 |
                 }
515 | 50 |
             }
516 | 10 |
         }
517 |  |
518 |  |
519 |  |
         /**
520 |  |
          * Populate the given context with the request-scope tools
521 |  |
          *
522 |  |
          * @param context a Velocity Context to populate
523 |  |
          * @param data a RunData instance
524 |  |
          */
525 |  |
         private void populateWithRequestTools(Context context, PipelineData pipelineData)
526 |  |
         {
527 |  |
             // Iterate the tools
528 | 6 |
             for (Iterator<ToolData> it = requestTools.iterator(); it.hasNext();)
529 |  |
             {
530 | 30 |
                 ToolData toolData = it.next();
531 |  |
                 try
532 |  |
                 {
533 |  |
                     // Fetch Object through the Pool.
534 | 30 |
                     Object tool = pool.getInstance(toolData.toolClass);
535 |  |
536 | 30 |
                     initTool(tool, pipelineData);
537 |  |
538 |  |
                     // put the tool in the context
539 | 30 |
                     context.put(toolData.toolName, tool);
540 |  |
                 }
541 | 0 |
                 catch (Exception e)
542 |  |
                 {
543 | 0 |
                     log.error("Could not instantiate request tool "
544 |  |
                         + toolData.toolName + " from a "
545 |  |
                         + toolData.toolClassName + " object", e);
546 | 30 |
                 }
547 | 30 |
             }
548 | 6 |
         }
549 |  |
550 |  |
         /**
551 |  |
          * Populate the given context with the session-scoped tools.
552 |  |
          *
553 |  |
          * @param tools The list of tools with which to populate the
554 |  |
          * session.
555 |  |
          * @param context The context to populate.
556 |  |
          * @param data The current RunData object
557 |  |
          * @param user The <code>User</code> object whose storage to
558 |  |
          * retrieve the tool from.
559 |  |
          */
560 |  |
         @SuppressWarnings({ "unused", "null" })
561 |  |
         private void populateWithSessionTools(List<ToolData> tools, Context context,
562 |  |
                 PipelineData pipelineData, User user)
563 |  |
         {
564 |  |
             //Map runDataMap = (Map)pipelineData.get(RunData.class);
565 |  |
             //RunData data = (RunData) runDataMap.get(RunData.class);
566 | 8 |
             RunData runData = (RunData)pipelineData;
567 |  |
             // Iterate the tools
568 | 8 |
             for (Iterator<ToolData> it = tools.iterator(); it.hasNext();)
569 |  |
             {
570 | 6 |
                 ToolData toolData = it.next();
571 |  |
                 try
572 |  |
                 {
573 |  |
                     // ensure that tool is created only once for a user
574 |  |
                     // by synchronizing against the user object
575 | 6 |
                     synchronized (runData.getSession())
576 |  |
                     {
577 |  |
                         // first try and fetch the tool from the user's
578 |  |
                         // hashtable
579 | 6 |
                         Object tool = runData.getSession().getAttribute(
580 |  |
                                 SESSION_TOOLS_ATTRIBUTE_PREFIX
581 |  |
                                 + toolData.toolClassName);
582 |  |
583 | 6 |
                         if (tool == null)
584 |  |
                         {
585 |  |
                             // if not there, an instance must be fetched from
586 |  |
                             // the pool
587 | 6 |
                             tool = pool.getInstance(toolData.toolClass);
588 |  |
589 |  |
                             // session tools are init'd with the User object
590 | 6 |
                             initTool(tool, user);
591 |  |
592 |  |
                             // store the newly created tool in the session
593 | 6 |
                             runData.getSession().setAttribute(
594 |  |
                                     SESSION_TOOLS_ATTRIBUTE_PREFIX
595 |  |
                                     + tool.getClass().getName(), tool);
596 |  |
                         }
597 |  |
598 |  |
                         // *NOT* else
599 | 6 |
                         if(tool != null)
600 |  |
                         {
601 |  |
                             // This is a semantics change. In the old
602 |  |
                             // Turbine, Session tools were initialized and
603 |  |
                             // then refreshed every time they were pulled
604 |  |
                             // into the context if "refreshToolsPerRequest"
605 |  |
                             // was wanted.
606 |  |
                             //
607 |  |
                             // RunDataApplicationTools now have a parameter
608 |  |
                             // for refresh. If it is not refreshed immediately
609 |  |
                             // after init(), the parameter value will be undefined
610 |  |
                             // until the 2nd run. So we refresh all the session
611 |  |
                             // tools on every run, even if we just init'ed it.
612 |  |
                             //
613 |  |
614 | 6 |
                             if (refreshToolsPerRequest)
615 |  |
                             {
616 | 6 |
                                 refreshTool(tool, pipelineData);
617 |  |
                             }
618 |  |
619 |  |
                             // put the tool in the context
620 | 6 |
                             log.debug("Adding " + tool + " to ctx as "
621 |  |
                                     + toolData.toolName);
622 | 6 |
                             context.put(toolData.toolName, tool);
623 |  |
                         }
624 |  |
                         else
625 |  |
                         {
626 | 0 |
                             log.info("Tool " + toolData.toolName
627 |  |
                                     + " was null, skipping it.");
628 |  |
                         }
629 | 6 |
                     }
630 |  |
                 }
631 | 0 |
                 catch (Exception e)
632 |  |
                 {
633 | 0 |
                     log.error("Could not instantiate session tool "
634 |  |
                         + toolData.toolName + " from a "
635 |  |
                         + toolData.toolClassName + " object", e);
636 | 6 |
                 }
637 | 6 |
             }
638 | 8 |
         }
639 |  |
640 |  |
         /**
641 |  |
          * Populate the given context with the session-scoped tools.
642 |  |
          *
643 |  |
          * @param tools The list of tools with which to populate the
644 |  |
          * session.
645 |  |
          * @param context The context to populate.
646 |  |
          * @param data The current RunData object
647 |  |
          * @param user The <code>User</code> object whose storage to
648 |  |
          * retrieve the tool from.
649 |  |
          */
650 |  |
         @SuppressWarnings({ "unused", "null" })
651 |  |
         private void populateWithSessionTools(List<ToolData> tools, Context context,
652 |  |
                 RunData data, User user)
653 |  |
         {
654 |  |
             // Iterate the tools
655 | 10 |
             for (Iterator<ToolData> it = tools.iterator(); it.hasNext();)
656 |  |
             {
657 | 10 |
                 ToolData toolData = it.next();
658 |  |
                 try
659 |  |
                 {
660 |  |
                     // ensure that tool is created only once for a user
661 |  |
                     // by synchronizing against the user object
662 | 10 |
                     synchronized (data.getSession())
663 |  |
                     {
664 |  |
                         // first try and fetch the tool from the user's
665 |  |
                         // hashtable
666 | 10 |
                         Object tool = data.getSession().getAttribute(
667 |  |
                                 SESSION_TOOLS_ATTRIBUTE_PREFIX
668 |  |
                                 + toolData.toolClassName);
669 |  |
670 | 10 |
                         if (tool == null)
671 |  |
                         {
672 |  |
                             // if not there, an instance must be fetched from
673 |  |
                             // the pool
674 | 10 |
                             tool = pool.getInstance(toolData.toolClass);
675 |  |
676 |  |
                             // session tools are init'd with the User object
677 | 10 |
                             initTool(tool, user);
678 |  |
679 |  |
                             // store the newly created tool in the session
680 | 10 |
                             data.getSession().setAttribute(
681 |  |
                                     SESSION_TOOLS_ATTRIBUTE_PREFIX
682 |  |
                                     + tool.getClass().getName(), tool);
683 |  |
                         }
684 |  |
685 |  |
                         // *NOT* else
686 | 10 |
                         if(tool != null)
687 |  |
                         {
688 |  |
                             // This is a semantics change. In the old
689 |  |
                             // Turbine, Session tools were initialized and
690 |  |
                             // then refreshed every time they were pulled
691 |  |
                             // into the context if "refreshToolsPerRequest"
692 |  |
                             // was wanted.
693 |  |
                             //
694 |  |
                             // RunDataApplicationTools now have a parameter
695 |  |
                             // for refresh. If it is not refreshed immediately
696 |  |
                             // after init(), the parameter value will be undefined
697 |  |
                             // until the 2nd run. So we refresh all the session
698 |  |
                             // tools on every run, even if we just init'ed it.
699 |  |
                             //
700 |  |
701 | 10 |
                             if (refreshToolsPerRequest)
702 |  |
                             {
703 | 10 |
                                 refreshTool(tool, data);
704 |  |
                             }
705 |  |
706 |  |
                             // put the tool in the context
707 | 10 |
                             log.debug("Adding " + tool + " to ctx as "
708 |  |
                                     + toolData.toolName);
709 | 10 |
                             context.put(toolData.toolName, tool);
710 |  |
                         }
711 |  |
                         else
712 |  |
                         {
713 | 0 |
                             log.info("Tool " + toolData.toolName
714 |  |
                                     + " was null, skipping it.");
715 |  |
                         }
716 | 10 |
                     }
717 |  |
                 }
718 | 0 |
                 catch (Exception e)
719 |  |
                 {
720 | 0 |
                     log.error("Could not instantiate session tool "
721 |  |
                         + toolData.toolName + " from a "
722 |  |
                         + toolData.toolClassName + " object", e);
723 | 10 |
                 }
724 | 10 |
             }
725 | 10 |
         }
726 |  |
727 |  |
728 |  |
729 |  |
         /**
730 |  |
          * Populate the given context with the perm-scoped tools.
731 |  |
          *
732 |  |
          * @param tools The list of tools with which to populate the
733 |  |
          * session.
734 |  |
          * @param context The context to populate.
735 |  |
          * @param data The current RunData object
736 |  |
          * @param user The <code>User</code> object whose storage to
737 |  |
          * retrieve the tool from.
738 |  |
          */
739 |  |
         private void populateWithPermTools(List<ToolData> tools, Context context,
740 |  |
                 PipelineData pipelineData, User user)
741 |  |
         {
742 |  |
             // Iterate the tools
743 | 2 |
             for (Iterator<ToolData> it = tools.iterator(); it.hasNext();)
744 |  |
             {
745 | 0 |
                 ToolData toolData = it.next();
746 |  |
                 try
747 |  |
                 {
748 |  |
                     // ensure that tool is created only once for a user
749 |  |
                     // by synchronizing against the user object
750 | 0 |
                     synchronized (user)
751 |  |
                     {
752 |  |
                         // first try and fetch the tool from the user's
753 |  |
                         // hashtable
754 | 0 |
                         Object tool = user.getPerm(toolData.toolClassName);
755 |  |
756 | 0 |
                         if (tool == null)
757 |  |
                         {
758 |  |
                             // if not there, an instance must be fetched from
759 |  |
                             // the pool
760 | 0 |
                             tool = pool.getInstance(toolData.toolClass);
761 |  |
762 |  |
                             // session tools are init'd with the User object
763 | 0 |
                             initTool(tool, user);
764 |  |
765 |  |
                             // store the newly created tool in the user's hashtable
766 | 0 |
                             user.setPerm(toolData.toolClassName, tool);
767 |  |
                         }
768 |  |
769 |  |
                         // *NOT* else
770 | 0 |
                         if(tool != null)
771 |  |
                         {
772 |  |
                             // This is a semantics change. In the old
773 |  |
                             // Turbine, Session tools were initialized and
774 |  |
                             // then refreshed every time they were pulled
775 |  |
                             // into the context if "refreshToolsPerRequest"
776 |  |
                             // was wanted.
777 |  |
                             //
778 |  |
                             // RunDataApplicationTools now have a parameter
779 |  |
                             // for refresh. If it is not refreshed immediately
780 |  |
                             // after init(), the parameter value will be undefined
781 |  |
                             // until the 2nd run. So we refresh all the session
782 |  |
                             // tools on every run, even if we just init'ed it.
783 |  |
                             //
784 |  |
785 | 0 |
                             if (refreshToolsPerRequest)
786 |  |
                             {
787 | 0 |
                                 refreshTool(tool, pipelineData);
788 |  |
                             }
789 |  |
790 |  |
                             // put the tool in the context
791 | 0 |
                             log.debug("Adding " + tool + " to ctx as "
792 |  |
                                     + toolData.toolName);
793 | 0 |
                             log.warn("Persistent scope tools are deprecated.");
794 | 0 |
                             context.put(toolData.toolName, tool);
795 |  |
                         }
796 |  |
                         else
797 |  |
                         {
798 | 0 |
                             log.info("Tool " + toolData.toolName
799 |  |
                                     + " was null, skipping it.");
800 |  |
                         }
801 | 0 |
                     }
802 |  |
                 }
803 | 0 |
                 catch (Exception e)
804 |  |
                 {
805 | 0 |
                     log.error("Could not instantiate perm tool "
806 |  |
                         + toolData.toolName + " from a "
807 |  |
                         + toolData.toolClassName + " object", e);
808 | 0 |
                 }
809 | 0 |
             }
810 | 2 |
         }
811 |  |
812 |  |
         /**
813 |  |
          * Populate the given context with the perm-scoped tools.
814 |  |
          *
815 |  |
          * @param tools The list of tools with which to populate the
816 |  |
          * session.
817 |  |
          * @param context The context to populate.
818 |  |
          * @param data The current RunData object
819 |  |
          * @param user The <code>User</code> object whose storage to
820 |  |
          * retrieve the tool from.
821 |  |
          */
822 |  |
         private void populateWithPermTools(List<ToolData> tools, Context context,
823 |  |
                 RunData data, User user)
824 |  |
         {
825 |  |
             // Iterate the tools
826 | 0 |
             for (Iterator<ToolData> it = tools.iterator(); it.hasNext();)
827 |  |
             {
828 | 0 |
                 ToolData toolData = it.next();
829 |  |
                 try
830 |  |
                 {
831 |  |
                     // ensure that tool is created only once for a user
832 |  |
                     // by synchronizing against the user object
833 | 0 |
                     synchronized (user)
834 |  |
                     {
835 |  |
                         // first try and fetch the tool from the user's
836 |  |
                         // hashtable
837 | 0 |
                         Object tool = user.getPerm(toolData.toolClassName);
838 |  |
839 | 0 |
                         if (tool == null)
840 |  |
                         {
841 |  |
                             // if not there, an instance must be fetched from
842 |  |
                             // the pool
843 | 0 |
                             tool = pool.getInstance(toolData.toolClass);
844 |  |
845 |  |
                             // session tools are init'd with the User object
846 | 0 |
                             initTool(tool, user);
847 |  |
848 |  |
                             // store the newly created tool in the user's hashtable
849 | 0 |
                             user.setPerm(toolData.toolClassName, tool);
850 |  |
                         }
851 |  |
852 |  |
                         // *NOT* else
853 | 0 |
                         if(tool != null)
854 |  |
                         {
855 |  |
                             // This is a semantics change. In the old
856 |  |
                             // Turbine, Session tools were initialized and
857 |  |
                             // then refreshed every time they were pulled
858 |  |
                             // into the context if "refreshToolsPerRequest"
859 |  |
                             // was wanted.
860 |  |
                             //
861 |  |
                             // RunDataApplicationTools now have a parameter
862 |  |
                             // for refresh. If it is not refreshed immediately
863 |  |
                             // after init(), the parameter value will be undefined
864 |  |
                             // until the 2nd run. So we refresh all the session
865 |  |
                             // tools on every run, even if we just init'ed it.
866 |  |
                             //
867 |  |
868 | 0 |
                             if (refreshToolsPerRequest)
869 |  |
                             {
870 | 0 |
                                 refreshTool(tool, data);
871 |  |
                             }
872 |  |
873 |  |
                             // put the tool in the context
874 | 0 |
                             log.debug("Adding " + tool + " to ctx as "
875 |  |
                                     + toolData.toolName);
876 | 0 |
                             log.warn("Persistent scope tools are deprecated.");
877 | 0 |
                             context.put(toolData.toolName, tool);
878 |  |
                         }
879 |  |
                         else
880 |  |
                         {
881 | 0 |
                             log.info("Tool " + toolData.toolName
882 |  |
                                     + " was null, skipping it.");
883 |  |
                         }
884 | 0 |
                     }
885 |  |
                 }
886 | 0 |
                 catch (Exception e)
887 |  |
                 {
888 | 0 |
                     log.error("Could not instantiate perm tool "
889 |  |
                         + toolData.toolName + " from a "
890 |  |
                         + toolData.toolClassName + " object", e);
891 | 0 |
                 }
892 | 0 |
             }
893 | 0 |
         }
894 |  |
895 |  |
896 |  |
897 |  |
         /**
898 |  |
          * Return the absolute path to the resources directory
899 |  |
          * used by the application tools.
900 |  |
          *
901 |  |
          * @return the absolute path of the resources directory
902 |  |
          */
903 |  |
         public String getAbsolutePathToResourcesDirectory()
904 |  |
         {
905 | 0 |
             return Turbine.getRealPath(resourcesDirectory);
906 |  |
         }
907 |  |
908 |  |
         /**
909 |  |
          * Return the resources directory. This is
910 |  |
          * relative to the web context.
911 |  |
          *
912 |  |
          * @return the relative path of the resources directory
913 |  |
          */
914 |  |
         public String getResourcesDirectory()
915 |  |
         {
916 | 46 |
             return resourcesDirectory;
917 |  |
         }
918 |  |
919 |  |
         /**
920 |  |
          * Refresh the global tools. We can
921 |  |
          * only refresh those tools that adhere to
922 |  |
          * ApplicationTool interface because we
923 |  |
          * know those types of tools have a refresh
924 |  |
          * method.
925 |  |
          */
926 |  |
         private void refreshGlobalTools()
927 |  |
         {
928 | 28 |
             for (Iterator<ToolData> it = globalTools.iterator(); it.hasNext();)
929 |  |
             {
930 | 28 |
                 ToolData toolData = it.next();
931 | 28 |
                 Object tool = globalContext.get(toolData.toolName);
932 | 28 |
                 refreshTool(tool, null);
933 | 28 |
             }
934 | 28 |
         }
935 |  |
936 |  |
         /**
937 |  |
          * Release the request-scope tool instances in the
938 |  |
          * given Context back to the pool
939 |  |
          *
940 |  |
          * @param context the Velocity Context to release tools from
941 |  |
          */
942 |  |
         public void releaseTools(Context context)
943 |  |
         {
944 |  |
             // only the request tools can be released - other scoped
945 |  |
             // tools will have continuing references to them
946 | 2 |
             releaseTools(context, requestTools);
947 | 2 |
         }
948 |  |
949 |  |
         /**
950 |  |
          * Release the given list of tools from the context back
951 |  |
          * to the pool
952 |  |
          *
953 |  |
          * @param context the Context containing the tools
954 |  |
          * @param tools a List of ToolData objects
955 |  |
          */
956 |  |
         private void releaseTools(Context context, List<ToolData> tools)
957 |  |
         {
958 | 2 |
             for (Iterator<ToolData> it = tools.iterator(); it.hasNext();)
959 |  |
             {
960 | 10 |
                 ToolData toolData = it.next();
961 | 10 |
                 Object tool = context.remove(toolData.toolName);
962 |  |
963 | 10 |
                 if (tool != null)
964 |  |
                 {
965 | 10 |
                     pool.putInstance(tool);
966 |  |
                 }
967 | 10 |
             }
968 | 2 |
         }
969 |  |
970 |  |
         /**
971 |  |
          * Initialized a given Tool with the passed init Object
972 |  |
          *
973 |  |
          * @param tool A Tool Object
974 |  |
          * @param param The Init Parameter
975 |  |
          *
976 |  |
          * @throws Exception If anything went wrong.
977 |  |
          */
978 |  |
         private void initTool(Object tool, Object param)
979 |  |
             throws Exception
980 |  |
         {
981 | 142 |
             if (param instanceof PipelineData)
982 |  |
             {
983 | 80 |
                 if (tool instanceof PipelineDataApplicationTool)
984 |  |
                 {
985 | 0 |
                     ((PipelineDataApplicationTool) tool).init(param);
986 |  |
                 }
987 | 80 |
                 else if (tool instanceof RunDataApplicationTool)
988 |  |
                 {
989 | 0 |
                     RunData data = getRunData((PipelineData)param);
990 | 0 |
                     ((RunDataApplicationTool) tool).init(data);
991 | 0 |
                 }
992 | 80 |
                 else if (tool instanceof ApplicationTool)
993 |  |
                 {
994 | 80 |
                     RunData data = getRunData((PipelineData)param);
995 | 80 |
                     ((ApplicationTool) tool).init(data);
996 | 80 |
                 }
997 |  |
             }
998 |  |
             else
999 |  |
             {
1000 | 62 |
                 if (tool instanceof PipelineDataApplicationTool)
1001 |  |
                 {
1002 | 0 |
                     ((PipelineDataApplicationTool) tool).init(param);
1003 |  |
                 }
1004 | 62 |
                 else if (tool instanceof RunDataApplicationTool)
1005 |  |
                 {
1006 | 0 |
                     ((RunDataApplicationTool) tool).init(param);
1007 |  |
                 }
1008 | 62 |
                 else if (tool instanceof ApplicationTool)
1009 |  |
                 {
1010 | 62 |
                     ((ApplicationTool) tool).init(param);
1011 |  |
                 }
1012 |  |
             }
1013 | 142 |
         }
1014 |  |
1015 |  |
         /**
1016 |  |
          * Refresh a given Tool.
1017 |  |
          *
1018 |  |
          * @param tool A Tool Object
1019 |  |
          * @param data The current RunData Object
1020 |  |
          */
1021 |  |
         private void refreshTool(Object tool, Object dataObject)
1022 |  |
         {
1023 | 44 |
             RunData data = null;
1024 | 44 |
             PipelineData pipelineData = null;
1025 | 44 |
             if (dataObject instanceof PipelineData)
1026 |  |
             {
1027 | 16 |
                 pipelineData = (PipelineData)dataObject;
1028 | 16 |
                 data = getRunData(pipelineData);
1029 | 16 |
                 if (tool instanceof PipelineDataApplicationTool)
1030 |  |
                 {
1031 | 0 |
                     ((PipelineDataApplicationTool) tool).refresh(pipelineData);
1032 |  |
                 }
1033 |  |
             }
1034 | 44 |
             if (tool instanceof ApplicationTool)
1035 |  |
             {
1036 | 44 |
                 ((ApplicationTool) tool).refresh();
1037 |  |
             }
1038 | 0 |
             else if (tool instanceof RunDataApplicationTool)
1039 |  |
             {
1040 | 0 |
                 ((RunDataApplicationTool) tool).refresh(data);
1041 |  |
             }
1042 | 44 |
         }
1043 |  |
1044 |  |
         private RunData getRunData(PipelineData pipelineData)
1045 |  |
         {
1046 | 96 |
             if(!(pipelineData instanceof RunData)){
1047 | 0 |
                 throw new RuntimeException("Can't cast to rundata from pipeline data.");
1048 |  |
             }
1049 | 96 |
             return (RunData)pipelineData;
1050 |  |
         }
1051 |  |
     }