1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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);
144
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
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
200
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
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
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
251 return rule.apply(context, this);
252 }
253
254
255
256
257
258
259
260 public ProfileLocator getProfile(RequestContext context, ProfilingRule rule)
261 throws ProfilerException
262 {
263
264 return rule.apply(context, this);
265 }
266
267
268
269
270
271
272
273 public ProfilingRule getRuleForPrincipal(Principal principal,
274 String locatorName)
275 {
276 ProfilingRule rule = null;
277
278 PrincipalRule pr = lookupPrincipalRule(principal.getName(), locatorName);
279
280
281 if (pr == null)
282 {
283
284 rule = getRule(locatorName);
285
286 if (rule == null)
287 {
288
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
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
329
330
331
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();
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
391
392
393
394 public ProfilingRule getDefaultRule()
395 {
396 return getRule(this.defaultRule);
397 }
398
399
400
401
402
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
419
420
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
438
439
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
466
467
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
492
493
494
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
531
532
533
534 public void storeProfilingRule(ProfilingRule rule) throws ProfilerException
535 {
536 getPersistenceBrokerTemplate().store(rule);
537 }
538
539
540
541
542
543
544 public void deleteProfilingRule(ProfilingRule rule)
545 throws ProfilerException
546 {
547 getPersistenceBrokerTemplate().delete(rule);
548 }
549
550
551
552
553
554
555 public void storePrincipalRule(PrincipalRule rule) throws ProfilerException
556 {
557 getPersistenceBrokerTemplate().store(rule);
558 }
559
560
561
562
563
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
576
577
578
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
649
650
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
674
675
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
695
696
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
717
718
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 }