View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.jetspeed.profiler.impl;
18  
19  import java.security.Principal;
20  import java.util.Collection;
21  import java.util.Collections;
22  import java.util.HashMap;
23  import java.util.Iterator;
24  import java.util.Map;
25  import java.util.Properties;
26  
27  import javax.security.auth.Subject;
28  
29  import org.apache.commons.logging.Log;
30  import org.apache.commons.logging.LogFactory;
31  import org.apache.jetspeed.components.dao.InitablePersistenceBrokerDaoSupport;
32  import org.apache.jetspeed.profiler.ProfileLocator;
33  import org.apache.jetspeed.profiler.Profiler;
34  import org.apache.jetspeed.profiler.ProfilerException;
35  import org.apache.jetspeed.profiler.rules.PrincipalRule;
36  import org.apache.jetspeed.profiler.rules.ProfileResolvers;
37  import org.apache.jetspeed.profiler.rules.ProfilingRule;
38  import org.apache.jetspeed.profiler.rules.RuleCriterion;
39  import org.apache.jetspeed.profiler.rules.impl.AbstractProfilingRule;
40  import org.apache.jetspeed.profiler.rules.impl.PrincipalRuleImpl;
41  import org.apache.jetspeed.request.RequestContext;
42  import org.apache.jetspeed.security.SecurityHelper;
43  import org.apache.jetspeed.security.UserPrincipal;
44  import org.apache.jetspeed.security.impl.UserPrincipalImpl;
45  import org.apache.ojb.broker.query.Criteria;
46  import org.apache.ojb.broker.query.QueryFactory;
47  import org.springframework.beans.BeansException;
48  import org.springframework.beans.factory.BeanFactory;
49  import org.springframework.beans.factory.BeanFactoryAware;
50  
51  /***
52   * JetspeedTransactionalProfiler
53   * 
54   * @author <a href="mailto:taylor@apache.org">David Sean Taylor </a>
55   * @version $Id: JetspeedProfilerImpl.java 553647 2007-07-05 21:42:04Z taylor $
56   */
57  public class JetspeedProfilerImpl extends InitablePersistenceBrokerDaoSupport 
58          implements Profiler, BeanFactoryAware
59  {
60      /*** The default rule. */
61      public final static String DEFAULT_RULE = "j1";
62      
63      /*** Commons logging */
64      protected final static Log log = LogFactory.getLog(JetspeedProfilerImpl.class);
65  
66      /***
67       * This is the princapl that is used if there are no principal to rule associations for the current principal
68       */
69      public final static Principal DEFAULT_RULE_PRINCIPAL = new UserPrincipalImpl("*");
70  
71      /*** The default locator class implementation */
72      private String locatorBean = "ProfileLocator";
73  
74      /*** The default principalRule association class implementation */
75      private Class prRuleClass;
76      
77      private String principalRuleBean = "PrincipalRule";
78      
79      /*** The base (abstract) profilingRule class implementation */
80      private String profilingRuleStandardBean = "StandardProfilingRule";
81      
82      /*** The base (abstract) profilingRule class implementation */
83      private String profilingRuleFallbackBean = "RoleFallbackProfilingRule";    
84      
85      /*** The base (abstract) profilingRule class implementation */
86      private Class profilingRuleClass = AbstractProfilingRule.class;
87  
88      /*** The configured default rule for this portal */
89      private String defaultRule = DEFAULT_RULE;
90  
91      private Map principalRules = Collections.synchronizedMap(new HashMap());
92  
93      private Map rulesPerPrincipal = Collections.synchronizedMap(new HashMap());
94  
95      private ProfileResolvers resolvers;
96  
97      /*** the default criterion bean name */
98      private String ruleCriterionBean = "RuleCriterion";
99  
100     /***
101      * added support for bean factory to create profile rules
102      */
103     private BeanFactory beanFactory;
104 
105     public JetspeedProfilerImpl(String repositoryPath,
106             ProfileResolvers resolvers)
107     {
108         super(repositoryPath);
109         this.resolvers = resolvers;
110     }
111 
112     /***
113      * Create a JetspeedProfiler with properties. Expected properties are:
114      * defaultRule = the default profiling rule anonymousUser = the name of the
115      * anonymous user storeName = The name of the persistence store component to
116      * connect to services.profiler.locator.impl = the pluggable Profile Locator
117      * impl services.profiler.principalRule.impl = the pluggable Principal Rule
118      * impl services.profiler.profilingRule.impl = the pluggable Profiling Rule
119      * impl
120      * 
121      * @param properties
122      *            Properties for this component described above
123      * @throws ClassNotFoundException
124      *             if any the implementation classes defined within the
125      *             <code>properties</code> argument could not be found.
126      */
127     public JetspeedProfilerImpl(String repositoryPath, String defaultRule,
128             ProfileResolvers resolvers) throws ClassNotFoundException
129     {
130         this(repositoryPath, resolvers);
131         this.defaultRule = defaultRule;
132     }
133 
134     /***
135      * @deprecated As of release 2.1, property-based class references replaced
136      *             by container managed bean factory
137      */
138     public JetspeedProfilerImpl(String repositoryPath, String defaultRule,
139             Properties properties, ProfileResolvers resolvers)
140             throws ClassNotFoundException
141     {
142         this(repositoryPath, defaultRule, resolvers);
143         initModelClasses(properties); // TODO: move this to
144         // start()
145     }
146 
147     /***
148      * support passing of rule creation classes
149      */
150     public JetspeedProfilerImpl(String repositoryPath, String defaultRule,
151             ProfileResolvers resolvers, Map ruleConstructors,
152             String ruleCriterionBean) throws ClassNotFoundException
153     {
154         this(repositoryPath, defaultRule, resolvers);
155         this.ruleCriterionBean = ruleCriterionBean;
156         initRuleClasses(ruleConstructors);
157     }
158 
159     /***
160      * @param defaultRule
161      *            The default rule to set.
162      */
163     public void setDefaultRule(String defaultRule)
164     {
165         this.defaultRule = defaultRule;
166     }
167 
168     /***
169      * @deprecated As of release 2.1, property-based class references replaced
170      *             by container managed bean factory
171      */
172     private void initModelClasses(Properties properties)
173             throws ClassNotFoundException
174     {
175 
176         /***
177          * String modelName = "";
178          * 
179          * if ((modelName = properties.getProperty("locator.impl")) != null) { //
180          * locatorClassName = modelName; } if ((modelName =
181          * properties.getProperty("principalRule.impl")) != null) {
182          * principalRuleClass = Class.forName(modelName); } if ((modelName =
183          * properties.getProperty("profilingRule.impl")) != null) {
184          * profilingRuleClass = Class.forName(modelName); }
185          */
186     }
187 
188     public ProfileLocator getProfile(RequestContext context, String locatorName)
189             throws ProfilerException
190     {
191         // get the principal representing the currently logged on user
192         Subject subject = context.getSubject();
193         if (subject == null)
194         {
195             String msg = "Invalid (null) Subject in request pipeline";
196             log.error(msg);
197             throw new ProfilerException(msg);
198         }
199         // get the UserPrincipal, finding the first UserPrincipal, or
200         // find the first principal if no UserPrincipal isn't available
201         Principal principal = SecurityHelper.getBestPrincipal(subject,
202                 UserPrincipal.class);
203         if (principal == null)
204         {
205             String msg = "Could not find a principle for subject in request pipeline";
206             log.error(msg);
207             throw new ProfilerException(msg);
208         }
209 
210         // find a profiling rule for this principal
211         ProfilingRule rule = getRuleForPrincipal(principal, locatorName);
212         if (null == rule)
213         {
214             log.warn("Could not find profiling rule for principal: "
215                     + principal);
216             rule = this.getDefaultRule();
217         }
218 
219         if (null == rule)
220         {
221             String msg = "Couldn't find any profiling rules including default rule for principal "
222                     + principal;
223             log.error(msg);
224             throw new ProfilerException(msg);
225         }
226         // create a profile locator for given rule
227         return rule.apply(context, this);
228     }
229 
230     public ProfileLocator getDefaultProfile(RequestContext context,
231             String locatorName) throws ProfilerException
232     {
233 
234         ProfilingRule rule = getRuleForPrincipal(DEFAULT_RULE_PRINCIPAL,
235                 locatorName);
236         if (null == rule)
237         {
238             log.warn("Could not find profiling rule for principal: "
239                     + DEFAULT_RULE_PRINCIPAL);
240             rule = this.getDefaultRule();
241         }
242 
243         if (null == rule)
244         {
245             String msg = "Couldn't find any profiling rules including default rule for principal "
246                     + DEFAULT_RULE_PRINCIPAL;
247             log.error(msg);
248             throw new ProfilerException(msg);
249         }
250         // create a profile locator for given rule
251         return rule.apply(context, this);
252     }
253 
254     /*
255      * (non-Javadoc)
256      * 
257      * @see org.apache.jetspeed.profiler.Profiler#getProfile(org.apache.jetspeed.request.RequestContext,
258      *      org.apache.jetspeed.profiler.rules.ProfilingRule)
259      */
260     public ProfileLocator getProfile(RequestContext context, ProfilingRule rule)
261             throws ProfilerException
262     {
263         // create a profile locator for given rule
264         return rule.apply(context, this);
265     }
266 
267     /*
268      * (non-Javadoc)
269      * 
270      * @see org.apache.jetspeed.profiler.Profiler#getRuleForPrincipal(java.security.Principal,
271      *      java.lang.String)
272      */
273     public ProfilingRule getRuleForPrincipal(Principal principal,
274             String locatorName)
275     {
276         ProfilingRule rule = null;
277         // lookup the rule for the given principal in our user/rule table
278         PrincipalRule pr = lookupPrincipalRule(principal.getName(), locatorName);
279 
280         // if not found, fallback to the locator named rule or system wide rule
281         if (pr == null)
282         {
283             // find rule on locator name
284             rule = getRule(locatorName);
285 
286             if (rule == null)
287             {
288                 // if not found, fallback to the system wide rule
289                 rule = getDefaultRule();
290             }
291             pr = new PrincipalRuleImpl();
292             pr.setLocatorName(locatorName);
293             pr.setPrincipalName(principal.getName());
294             pr.setProfilingRule(rule);
295             principalRules.put(makePrincipalRuleKey(principal.getName(),
296                     locatorName), pr);
297         } else
298         {
299             // Get the associated rule
300             rule = pr.getProfilingRule();
301         }
302 
303         return rule;
304     }
305 
306     /***
307      * Internal method to ensure we have a valid principalRule class for queries
308      * 
309      * @return the class object for the principalRule
310      */
311     private Class getPrincipalRuleClass()
312     {
313         if (this.prRuleClass == null)
314         {
315             try
316             {
317                 PrincipalRule tempRule = createPrincipalRule();
318                 this.prRuleClass = tempRule.getClass();
319             } catch (Exception e)
320             {
321                 e.printStackTrace();
322             }
323         }
324         return this.prRuleClass;
325     }
326 
327     /*
328      * (non-Javadoc)
329      * 
330      * @see org.apache.jetspeed.profiler.Profiler#setRuleForPrincipal(java.security.Principal,
331      *      org.apache.jetspeed.profiler.rules.ProfilingRule, java.lang.String)
332      */
333     public void setRuleForPrincipal(Principal principal, ProfilingRule rule,
334             String locatorName)
335     {
336         Criteria c = new Criteria();
337         c.addEqualTo("principalName", principal.getName());
338         c.addEqualTo("locatorName", locatorName);
339         PrincipalRule pr = (PrincipalRule) getPersistenceBrokerTemplate()
340                 .getObjectByQuery(
341                         QueryFactory.newQuery(getPrincipalRuleClass(), c));
342 
343         if (pr == null)
344         {
345             pr = new PrincipalRuleImpl(); // TODO: factory
346             pr.setPrincipalName(principal.getName());
347             pr.setLocatorName(locatorName);
348             pr.setProfilingRule(rule);
349         }
350         rule.setResolvers(resolvers);
351         pr.setProfilingRule(rule);
352         getPersistenceBrokerTemplate().store(pr);
353         principalRules.put(makePrincipalRuleKey(principal.getName(),
354                 locatorName), pr);
355         this.rulesPerPrincipal.remove(principal.getName());
356     }
357 
358     private String makePrincipalRuleKey(String principal, String locator)
359     {
360         return principal + ":" + locator;
361     }
362 
363     /***
364      * Helper function to lookup principal rule associations by principal
365      * 
366      * @param principal
367      *            The string representation of the principal name.
368      * @return The found PrincipalRule associated with the principal key or null
369      *         if not found.
370      */
371     private PrincipalRule lookupPrincipalRule(String principal,
372             String locatorName)
373     {
374         PrincipalRule pr = (PrincipalRule) principalRules
375                 .get(makePrincipalRuleKey(principal, locatorName));
376         if (pr != null) { return pr; }
377         Criteria c = new Criteria();
378         c.addEqualTo("principalName", principal);
379         c.addEqualTo("locatorName", locatorName);
380 
381         pr = (PrincipalRule) getPersistenceBrokerTemplate().getObjectByQuery(
382                 QueryFactory.newQuery(getPrincipalRuleClass(), c));
383 
384         principalRules.put(makePrincipalRuleKey(principal, locatorName), pr);
385         if (pr != null) pr.getProfilingRule().setResolvers(resolvers);
386         return pr;
387     }
388 
389     /*
390      * (non-Javadoc)
391      * 
392      * @see org.apache.jetspeed.profiler.Profiler#getDefaultRule()
393      */
394     public ProfilingRule getDefaultRule()
395     {
396         return getRule(this.defaultRule);
397     }
398 
399     /*
400      * (non-Javadoc)
401      * 
402      * @see org.apache.jetspeed.profiler.Profiler#getRules()
403      */
404     public Collection getRules()
405     {
406         Collection rules = getPersistenceBrokerTemplate().getCollectionByQuery(
407                 QueryFactory.newQuery(profilingRuleClass, new Criteria()));
408         Iterator r = rules.iterator();
409         while (r.hasNext())
410         {
411             ProfilingRule rule = (ProfilingRule) r.next();
412             rule.setResolvers(resolvers);
413         }
414         return rules;
415     }
416 
417     /*
418      * (non-Javadoc)
419      * 
420      * @see org.apache.jetspeed.profiler.Profiler#getRule(java.lang.String)
421      */
422     public ProfilingRule getRule(String id)
423     {
424         Criteria c = new Criteria();
425         c.addEqualTo("id", id);
426 
427         ProfilingRule rule = (ProfilingRule) getPersistenceBrokerTemplate()
428                 .getObjectByQuery(QueryFactory.newQuery(profilingRuleClass, c));
429         if (rule != null)
430         {
431             rule.setResolvers(resolvers);
432         }
433         return rule;
434     }
435 
436     /*
437      * (non-Javadoc)
438      * 
439      * @see org.apache.jetspeed.profiler.Profiler#getLocatorNamesForPrincipal(java.security.Principal)
440      */
441     public String[] getLocatorNamesForPrincipal(Principal principal)
442     {
443         Criteria c = new Criteria();
444         c.addEqualTo("principalName", principal.getName());
445 
446         Collection result = getPersistenceBrokerTemplate()
447                 .getCollectionByQuery(
448                         QueryFactory.newQuery(getPrincipalRuleClass(), c));
449         if (result.size() == 0) { return new String[]
450         {}; }
451         String[] names = new String[result.size()];
452         Iterator it = result.iterator();
453         int ix = 0;
454         while (it.hasNext())
455         {
456             PrincipalRule pr = (PrincipalRule) it.next();
457             names[ix] = pr.getLocatorName();
458             pr.getProfilingRule().setResolvers(resolvers);
459             ix++;
460         }
461         return names;
462     }
463 
464     /*
465      * (non-Javadoc)
466      * 
467      * @see org.apache.jetspeed.profiler.Profiler#getRulesForPrincipal(java.security.Principal)
468      */
469     public Collection getRulesForPrincipal(Principal principal)
470     {
471 
472         Collection rules = (Collection) this.rulesPerPrincipal.get(principal
473                 .getName());
474         if (rules != null) return rules;
475         Criteria c = new Criteria();
476         c.addEqualTo("principalName", principal.getName());
477         rules = getPersistenceBrokerTemplate().getCollectionByQuery(
478                 QueryFactory.newQuery(getPrincipalRuleClass(), c));
479         Iterator r = rules.iterator();
480         while (r.hasNext())
481         {
482             PrincipalRule pr = (PrincipalRule) r.next();
483             ProfilingRule rule = pr.getProfilingRule();
484             if (rule != null) rule.setResolvers(resolvers);
485         }
486         this.rulesPerPrincipal.put(principal.getName(), rules);
487         return rules;
488     }
489 
490     /*
491      * (non-Javadoc)
492      * 
493      * @see org.apache.jetspeed.profiler.Profiler#getProfileLocators(org.apache.jetspeed.request.RequestContext,
494      *      java.security.Principal)
495      */
496     public Map getProfileLocators(RequestContext context, Principal principal)
497             throws ProfilerException
498     {
499         Map locators = new HashMap();
500         Collection rules = getRulesForPrincipal(principal);
501 
502         Iterator it = rules.iterator();
503         while (it.hasNext())
504         {
505             PrincipalRule pr = (PrincipalRule) it.next();
506             locators.put(pr.getLocatorName(), getProfile(context, pr
507                     .getLocatorName()));
508         }
509         return locators;
510     }
511 
512     public Map getDefaultProfileLocators(RequestContext context)
513             throws ProfilerException
514     {
515         Map locators = new HashMap();
516 
517         Collection rules = getRulesForPrincipal(DEFAULT_RULE_PRINCIPAL);
518 
519         Iterator it = rules.iterator();
520         while (it.hasNext())
521         {
522             PrincipalRule pr = (PrincipalRule) it.next();
523             locators.put(pr.getLocatorName(), getDefaultProfile(context, pr
524                     .getLocatorName()));
525         }
526         return locators;
527     }
528 
529     /*
530      * (non-Javadoc)
531      * 
532      * @see org.apache.jetspeed.profiler.Profiler#storeProfilingRule(org.apache.jetspeed.profiler.rules.ProfilingRule)
533      */
534     public void storeProfilingRule(ProfilingRule rule) throws ProfilerException
535     {
536         getPersistenceBrokerTemplate().store(rule);
537     }
538 
539     /*
540      * (non-Javadoc)
541      * 
542      * @see org.apache.jetspeed.profiler.Profiler#deleteProfilingRule(org.apache.jetspeed.profiler.rules.ProfilingRule)
543      */
544     public void deleteProfilingRule(ProfilingRule rule)
545             throws ProfilerException
546     {
547         getPersistenceBrokerTemplate().delete(rule);
548     }
549 
550     /*
551      * (non-Javadoc)
552      * 
553      * @see org.apache.jetspeed.profiler.Profiler#storePrincipalRule(org.apache.jetspeed.profiler.rules.PrincipalRule)
554      */
555     public void storePrincipalRule(PrincipalRule rule) throws ProfilerException
556     {
557         getPersistenceBrokerTemplate().store(rule);
558     }
559 
560     /*
561      * (non-Javadoc)
562      * 
563      * @see org.apache.jetspeed.profiler.Profiler#deletePrincipalRule(org.apache.jetspeed.profiler.rules.PrincipalRule)
564      */
565     public void deletePrincipalRule(PrincipalRule rule)
566             throws ProfilerException
567     {
568         getPersistenceBrokerTemplate().delete(rule);
569         rulesPerPrincipal.remove(rule.getPrincipalName());
570         String key = this.makePrincipalRuleKey(rule.getPrincipalName(), rule.getLocatorName());
571         principalRules.remove(key);                
572     }
573 
574     /*
575      * Method called automatically by Spring container upon initialization
576      * 
577      * @param beanFactory automatically provided by framework @throws
578      * BeansException
579      */
580     public void setBeanFactory(BeanFactory beanFactory) throws BeansException
581     {
582         this.beanFactory = beanFactory;
583     }
584 
585     /***
586      * added logic to get the settings for creating the various rule related
587      * instances
588      * 
589      * @param classes
590      * @throws ClassNotFoundException
591      */
592     private void initRuleClasses(Map beans) throws ClassNotFoundException
593     {
594 
595         String beanName = "";
596         try
597         {
598             if ((beanName = (String) beans.get("locator")) != null)
599             {
600                 this.locatorBean = beanName;
601             }
602         } catch (Exception e)
603         {
604             String msg = "Exception in setting locatorbeanName : "
605                     + e.getLocalizedMessage();
606             log.error(msg);
607         }
608         try
609         {
610             if ((beanName = (String) beans.get("principal")) != null)
611             {
612                 this.principalRuleBean = beanName;
613             }
614         } catch (Exception e)
615         {
616             String msg = "Exception in setting principalRulebeanName : "
617                     + e.getLocalizedMessage();
618             log.error(msg);
619         }
620         try
621         {
622             if ((beanName = (String) beans.get("standard")) != null)
623             {
624                 this.profilingRuleStandardBean = beanName;
625             }
626         } catch (Exception e)
627         {
628             String msg = "Exception in setting profilingRuleStandardbeanName : "
629                     + e.getLocalizedMessage();
630             log.error(msg);
631         }
632         try
633         {
634             if ((beanName = (String) beans.get("fallback")) != null)
635             {
636                 this.profilingRuleFallbackBean = beanName;
637             }
638         } catch (Exception e)
639         {
640             String msg = "Exception in setting profilingRuleFallback : "
641                     + e.getLocalizedMessage();
642             log.error(msg);
643         }
644 
645     }
646 
647     /*
648      * (non-Javadoc)
649      * 
650      * @see org.apache.jetspeed.profiler.Profiler#createProfilingRule(boolean)
651      */
652     public ProfilingRule createProfilingRule(boolean standard)
653             throws ClassNotFoundException
654     {
655         try
656         {
657             if (standard)
658                 return (ProfilingRule) beanFactory.getBean(
659                         this.profilingRuleStandardBean, ProfilingRule.class);
660             else
661                 return (ProfilingRule) beanFactory.getBean(
662                         this.profilingRuleFallbackBean, ProfilingRule.class);
663 
664         } catch (BeansException e)
665         {
666             throw new ClassNotFoundException("Spring failed to create the "
667                     + (standard ? "standard" : "fallback")
668                     + " profiling rule bean.", e);
669         }
670     }
671 
672     /*
673      * (non-Javadoc)
674      * 
675      * @see org.apache.jetspeed.profiler.Profiler#createLocator(RequestContext)
676      */
677     public ProfileLocator createLocator(RequestContext context)
678     {
679         try
680         {
681             ProfileLocator locator = (ProfileLocator) beanFactory.getBean(
682                     this.locatorBean, ProfileLocator.class);
683             locator.init(this, context.getPath());
684             return locator;
685         } catch (Exception e)
686         {
687             log.error("Failed to create locator for " + this.locatorBean
688                     + " error : " + e.getLocalizedMessage());
689         }
690         return null;
691     }
692 
693     /*
694      * (non-Javadoc)
695      * 
696      * @see org.apache.jetspeed.profiler.Profiler#createPrincipalRule()
697      */
698     public PrincipalRule createPrincipalRule() throws ClassNotFoundException
699     {
700         try
701         {
702             PrincipalRule principalRule = (PrincipalRule) beanFactory.getBean(
703                     this.principalRuleBean, PrincipalRule.class);
704             return principalRule;
705         } catch (Exception e)
706         {
707             log.error("Failed to create principalRule for " + principalRuleBean
708                     + " error : " + e.getLocalizedMessage());
709             throw new ClassNotFoundException("Spring failed to create the "
710                     + " principal rule bean.", e);
711         }
712 
713     }
714 
715     /*
716      * (non-Javadoc)
717      * 
718      * @see org.apache.jetspeed.profiler.Profiler#createRuleCriterion()
719      */
720     public RuleCriterion createRuleCriterion() throws ClassNotFoundException
721     {
722         try
723         {
724             RuleCriterion ruleCriterion = (RuleCriterion) beanFactory.getBean(
725                     this.ruleCriterionBean, RuleCriterion.class);
726             return ruleCriterion;
727         } catch (Exception e)
728         {
729             log.error("Failed to create principalRule for " + ruleCriterionBean
730                     + " error : " + e.getLocalizedMessage());
731             throw new ClassNotFoundException("Spring failed to create the "
732                     + " rule criterion bean.", e);
733         }
734 
735     }
736 
737 }