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

Classes in this File | Line Coverage | Branch Coverage | Complexity
TurbinePullService |
57% | 136/238
44% | 41/92
| 3.5652173913043477;3,565
TurbinePullService$ToolData |
100% | 5/5
N/A | N/A
| 3.5652173913043477;3,565

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.annotation.AnnotationProcessor;
35 |  |
     import org.apache.turbine.om.security.User;
36 |  |
     import org.apache.turbine.pipeline.PipelineData;
37 |  |
     import org.apache.turbine.services.InitializationException;
38 |  |
     import org.apache.turbine.services.TurbineBaseService;
39 |  |
     import org.apache.turbine.services.TurbineServices;
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 &lt;id&gt; 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 1773378 2016-12-09 13:19:59Z tv $
120 |  |
      */
121 | 32 |
     public class TurbinePullService
122 |  |
             extends TurbineBaseService
123 |  |
             implements PullService
124 |  |
     {
125 |  |
         /** Logging */
126 | 32 |
         private static Log log = LogFactory.getLog(TurbinePullService.class);
127 |  |
128 |  |
         /** Reference to the pool service */
129 | 32 |
         private PoolService pool = null;
130 |  |
131 |  |
         /** Reference to the templating (nee Velocity) service */
132 | 32 |
         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 | 133 |
             {
157 | 133 |
                 this.toolName = toolName;
158 | 133 |
                 this.toolClassName = toolClassName;
159 | 133 |
                 this.toolClass = toolClass;
160 | 133 |
             }
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 | 32 |
         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 | 39 |
                         pool = (PoolService)TurbineServices.getInstance().getService(PoolService.ROLE);
194 |  |
195 | 39 |
                 if (pool == null)
196 |  |
                 {
197 | 0 |
                     throw new InitializationException("Pull Service requires"
198 |  |
                         + " configured Pool Service!");
199 |  |
                 }
200 |  |
201 | 39 |
                 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 | 39 |
                 setInit(true);
206 |  |
207 |  |
                 // Do _NOT_ move this before the setInit(true)
208 | 39 |
                 velocity = (VelocityService)TurbineServices.getInstance().getService(VelocityService.SERVICE_NAME);
209 |  |
210 | 28 |
                 if (velocity != null)
211 |  |
                 {
212 | 28 |
                     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("TurbinePullService failed to initialize", e);
222 | 28 |
             }
223 | 28 |
         }
224 |  |
225 |  |
         /**
226 |  |
          * Initialize the pull service
227 |  |
          *
228 |  |
          * @throws Exception A problem happened when starting up
229 |  |
          */
230 |  |
         private void initPullService()
231 |  |
             throws Exception
232 |  |
         {
233 |  |
             // This is the per-service configuration, prefixed with services.PullService
234 | 39 |
             Configuration conf = getConfiguration();
235 |  |
236 |  |
             // Get the resources directory that is specificed
237 |  |
             // in the TR.props or default to "resources", relative to the webapp.
238 | 39 |
             resourcesDirectory = conf.getString(
239 |  |
                 TOOL_RESOURCES_DIR_KEY,
240 |  |
                 TOOL_RESOURCES_DIR_DEFAULT);
241 |  |
242 |  |
             // Should we refresh the tool box on a per
243 |  |
             // request basis.
244 | 39 |
             refreshToolsPerRequest =
245 |  |
                 conf.getBoolean(
246 |  |
                     TOOLS_PER_REQUEST_REFRESH_KEY,
247 |  |
                     TOOLS_PER_REQUEST_REFRESH_DEFAULT);
248 |  |
249 |  |
             // Log the fact that the application tool box will
250 |  |
             // be refreshed on a per request basis.
251 | 39 |
             if (refreshToolsPerRequest)
252 |  |
             {
253 | 30 |
                 log.info("Pull Model tools will "
254 |  |
                     + "be refreshed on a per request basis.");
255 |  |
             }
256 | 39 |
         }
257 |  |
258 |  |
         /**
259 |  |
          * Initialize the pull tools. At this point, the
260 |  |
          * service must be marked as initialized, because the
261 |  |
          * tools may call the methods of this service via the
262 |  |
          * static facade class TurbinePull.
263 |  |
          *
264 |  |
          * @throws Exception A problem happened when starting up
265 |  |
          */
266 |  |
         private void initPullTools()
267 |  |
             throws Exception
268 |  |
         {
269 |  |
             // And for reasons I never really fully understood,
270 |  |
             // the tools directive is toplevel without the service
271 |  |
             // prefix. This is brain-damaged but for legacy reasons we
272 |  |
             // keep this. So this is the global turbine configuration:
273 | 28 |
             Configuration conf = Turbine.getConfiguration();
274 |  |
275 |  |
             // Grab each list of tools that are to be used (for global scope,
276 |  |
             // request scope, authorized scope, session scope and persistent
277 |  |
             // scope tools). They are specified respectively in the TR.props
278 |  |
             // like this:
279 |  |
             //
280 |  |
             // tool.global.ui = org.apache.turbine.util.pull.UIManager
281 |  |
             // tool.global.mm = org.apache.turbine.util.pull.MessageManager
282 |  |
             //
283 |  |
             // tool.request.link = org.apache.turbine.services.pull.tools.TemplateLink
284 |  |
             //
285 |  |
             // tool.session.basket = org.sample.util.ShoppingBasket;
286 |  |
             //
287 |  |
             // tool.persistent.ui = org.apache.turbine.services.pull.util.PersistentUIManager
288 |  |
289 | 28 |
             log.debug("Global Tools:");
290 | 28 |
             globalTools     = getTools(conf.subset(GLOBAL_TOOL));
291 | 28 |
             log.debug("Request Tools:");
292 | 28 |
             requestTools    = getTools(conf.subset(REQUEST_TOOL));
293 | 28 |
             log.debug("Session Tools:");
294 | 28 |
             sessionTools    = getTools(conf.subset(SESSION_TOOL));
295 | 28 |
             log.debug("Authorized Tools:");
296 | 28 |
             authorizedTools = getTools(conf.subset(AUTHORIZED_TOOL));
297 | 28 |
             log.debug("Persistent Tools:");
298 | 28 |
             persistentTools = getTools(conf.subset(PERSISTENT_TOOL));
299 |  |
300 |  |
             // Create and populate the global context right now
301 |  |
302 |  |
             // This is unholy, because it entwines the VelocityService and
303 |  |
             // the Pull Service even further. However, there isn't much we can
304 |  |
             // do for the 2.3 release. Expect this to go post-2.3
305 | 28 |
             globalContext = velocity.getNewContext();
306 |  |
307 | 28 |
             populateWithGlobalTools(globalContext);
308 | 28 |
         }
309 |  |
310 |  |
         /**
311 |  |
          * Retrieve the tool names and classes for the tools defined
312 |  |
          * in the configuration file with the prefix given.
313 |  |
          *
314 |  |
          * @param toolConfig The part of the configuration describing some tools
315 |  |
          */
316 |  |
         @SuppressWarnings("unchecked")
317 |  |
         private List<ToolData> getTools(Configuration toolConfig)
318 |  |
         {
319 | 140 |
             List<ToolData> tools = new ArrayList<ToolData>();
320 |  |
321 |  |
             // There might not be any tools for this prefix
322 |  |
             // so return an empty list.
323 | 140 |
             if (toolConfig == null)
324 |  |
             {
325 | 0 |
                 return tools;
326 |  |
             }
327 |  |
328 | 140 |
             for (Iterator<String> it = toolConfig.getKeys(); it.hasNext();)
329 |  |
             {
330 | 133 |
                 String toolName = it.next();
331 | 133 |
                 String toolClassName = toolConfig.getString(toolName);
332 |  |
333 |  |
                 try
334 |  |
                 {
335 |  |
                     // Create an instance of the tool class.
336 | 133 |
                     Class<ApplicationTool> toolClass = (Class<ApplicationTool>) Class.forName(toolClassName);
337 |  |
338 |  |
                     // Add the tool to the list being built.
339 | 133 |
                     tools.add(new ToolData(toolName, toolClassName, toolClass));
340 |  |
341 | 133 |
                     log.info("Tool " + toolClassName
342 |  |
                         + " to add to the context as '$" + toolName + "'");
343 |  |
                 }
344 |  |
                 // NoClassDefFoundError + ClassNotFoundException
345 | 0 |
                 catch (Throwable e)
346 |  |
                 {
347 | 0 |
                     log.error("Cannot instantiate tool class "
348 |  |
                         + toolClassName + ": ", e);
349 | 133 |
                 }
350 | 133 |
             }
351 |  |
352 | 140 |
             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 | 28 |
             for (Iterator<ToolData> it = globalTools.iterator(); it.hasNext();)
478 |  |
             {
479 | 19 |
                 ToolData toolData = it.next();
480 |  |
                 try
481 |  |
                 {
482 | 19 |
                     Object tool = toolData.toolClass.newInstance();
483 |  |
484 |  |
                     // global tools are init'd with a null data parameter
485 | 19 |
                     initTool(tool, null);
486 |  |
487 |  |
                     // put the tool in the context
488 | 19 |
                     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 | 19 |
                 }
496 | 19 |
             }
497 | 28 |
         }
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 |  |
                         // hashmap
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 | 19 |
             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 |
             if (globalTools != null)
942 |  |
             {
943 | 10 |
                 for (ToolData toolData : globalTools)
944 |  |
                 {
945 | 10 |
                     Object tool = globalContext.get(toolData.toolName);
946 | 10 |
                     refreshTool(tool, null);
947 | 10 |
                 }
948 |  |
             }
949 | 10 |
         }
950 |  |
951 |  |
         /**
952 |  |
          * Release the request-scope tool instances in the
953 |  |
          * given Context back to the pool
954 |  |
          *
955 |  |
          * @param context the Velocity Context to release tools from
956 |  |
          */
957 |  |
         @Override
958 |  |
         public void releaseTools(Context context)
959 |  |
         {
960 |  |
             // only the request tools can be released - other scoped
961 |  |
             // tools will have continuing references to them
962 | 2 |
             releaseTools(context, requestTools);
963 | 2 |
         }
964 |  |
965 |  |
         /**
966 |  |
          * Release the given list of tools from the context back
967 |  |
          * to the pool
968 |  |
          *
969 |  |
          * @param context the Context containing the tools
970 |  |
          * @param tools a List of ToolData objects
971 |  |
          */
972 |  |
         private void releaseTools(Context context, List<ToolData> tools)
973 |  |
         {
974 | 2 |
             if (tools != null)
975 |  |
             {
976 | 2 |
                 for (ToolData toolData : tools)
977 |  |
                 {
978 | 10 |
                     Object tool = context.remove(toolData.toolName);
979 |  |
980 | 10 |
                     if (tool != null)
981 |  |
                     {
982 | 10 |
                         pool.putInstance(tool);
983 |  |
                     }
984 | 10 |
                 }
985 |  |
             }
986 | 2 |
         }
987 |  |
988 |  |
         /**
989 |  |
          * Initialized a given Tool with the passed init Object
990 |  |
          *
991 |  |
          * @param tool A Tool Object
992 |  |
          * @param param The Init Parameter
993 |  |
          *
994 |  |
          * @throws Exception If anything went wrong.
995 |  |
          */
996 |  |
         private void initTool(Object tool, Object param)
997 |  |
             throws Exception
998 |  |
         {
999 | 73 |
             AnnotationProcessor.process(tool);
1000 |  |
1001 | 73 |
             if (param instanceof PipelineData)
1002 |  |
             {
1003 | 45 |
                 if (tool instanceof PipelineDataApplicationTool)
1004 |  |
                 {
1005 | 0 |
                     ((PipelineDataApplicationTool) tool).init(param);
1006 |  |
                 }
1007 | 45 |
                 else if (tool instanceof RunDataApplicationTool)
1008 |  |
                 {
1009 | 0 |
                     RunData data = getRunData((PipelineData)param);
1010 | 0 |
                     ((RunDataApplicationTool) tool).init(data);
1011 | 0 |
                 }
1012 | 45 |
                 else if (tool instanceof ApplicationTool)
1013 |  |
                 {
1014 | 45 |
                     RunData data = getRunData((PipelineData)param);
1015 | 45 |
                     ((ApplicationTool) tool).init(data);
1016 | 45 |
                 }
1017 |  |
             }
1018 |  |
             else
1019 |  |
             {
1020 | 28 |
                 if (tool instanceof PipelineDataApplicationTool)
1021 |  |
                 {
1022 | 0 |
                     ((PipelineDataApplicationTool) tool).init(param);
1023 |  |
                 }
1024 | 28 |
                 else if (tool instanceof RunDataApplicationTool)
1025 |  |
                 {
1026 | 0 |
                     ((RunDataApplicationTool) tool).init(param);
1027 |  |
                 }
1028 | 28 |
                 else if (tool instanceof ApplicationTool)
1029 |  |
                 {
1030 | 28 |
                     ((ApplicationTool) tool).init(param);
1031 |  |
                 }
1032 |  |
             }
1033 | 73 |
         }
1034 |  |
1035 |  |
         /**
1036 |  |
          * Refresh a given Tool.
1037 |  |
          *
1038 |  |
          * @param tool A Tool Object
1039 |  |
          * @param pipelineData The current RunData Object
1040 |  |
          */
1041 |  |
         private void refreshTool(Object tool, Object dataObject)
1042 |  |
         {
1043 | 19 |
             RunData data = null;
1044 | 19 |
             PipelineData pipelineData = null;
1045 | 19 |
             if (dataObject instanceof PipelineData)
1046 |  |
             {
1047 | 9 |
                 pipelineData = (PipelineData)dataObject;
1048 | 9 |
                 data = getRunData(pipelineData);
1049 | 9 |
                 if (tool instanceof PipelineDataApplicationTool)
1050 |  |
                 {
1051 | 0 |
                     ((PipelineDataApplicationTool) tool).refresh(pipelineData);
1052 |  |
                 }
1053 |  |
             }
1054 | 19 |
             if (tool instanceof ApplicationTool)
1055 |  |
             {
1056 | 19 |
                 ((ApplicationTool) tool).refresh();
1057 |  |
             }
1058 | 0 |
             else if (tool instanceof RunDataApplicationTool)
1059 |  |
             {
1060 | 0 |
                 ((RunDataApplicationTool) tool).refresh(data);
1061 |  |
             }
1062 | 19 |
         }
1063 |  |
1064 |  |
         private RunData getRunData(PipelineData pipelineData)
1065 |  |
         {
1066 | 54 |
             if(!(pipelineData instanceof RunData)){
1067 | 0 |
                 throw new RuntimeException("Can't cast to rundata from pipeline data.");
1068 |  |
             }
1069 | 54 |
             return (RunData)pipelineData;
1070 |  |
         }
1071 |  |
     }