1 16 package org.apache.cocoon.portal.profile.impl; 17 18 import java.util.ArrayList ; 19 import java.util.Collection ; 20 import java.util.HashMap ; 21 import java.util.Iterator ; 22 import java.util.List ; 23 import java.util.Map ; 24 25 import org.apache.avalon.framework.CascadingRuntimeException; 26 import org.apache.avalon.framework.activity.Disposable; 27 import org.apache.avalon.framework.activity.Initializable; 28 import org.apache.avalon.framework.container.ContainerUtil; 29 import org.apache.avalon.framework.context.Context; 30 import org.apache.avalon.framework.context.ContextException; 31 import org.apache.avalon.framework.context.Contextualizable; 32 import org.apache.avalon.framework.parameters.ParameterException; 33 import org.apache.avalon.framework.parameters.Parameterizable; 34 import org.apache.avalon.framework.parameters.Parameters; 35 import org.apache.avalon.framework.service.ServiceException; 36 import org.apache.avalon.framework.service.ServiceSelector; 37 import org.apache.cocoon.ProcessingException; 38 import org.apache.cocoon.portal.PortalService; 39 import org.apache.cocoon.portal.coplet.CopletData; 40 import org.apache.cocoon.portal.coplet.CopletFactory; 41 import org.apache.cocoon.portal.coplet.CopletInstanceData; 42 import org.apache.cocoon.portal.coplet.adapter.CopletAdapter; 43 import org.apache.cocoon.portal.layout.Layout; 44 import org.apache.cocoon.portal.profile.PortalUser; 45 import org.apache.cocoon.portal.profile.ProfileLS; 46 import org.apache.cocoon.util.ClassUtils; 47 import org.apache.commons.collections.map.LinkedMap; 48 import org.apache.commons.lang.exception.ExceptionUtils; 49 import org.apache.excalibur.source.SourceNotFoundException; 50 import org.apache.excalibur.source.SourceValidity; 51 52 73 public class GroupBasedProfileManager 74 extends AbstractProfileManager 75 implements Parameterizable, Contextualizable, Initializable, Disposable { 76 77 public static final String CATEGORY_GLOBAL = "global"; 78 public static final String CATEGORY_GROUP = "group"; 79 public static final String CATEGORY_USER = "user"; 80 81 protected static final String KEY_PREFIX = GroupBasedProfileManager.class.getName() + ':'; 82 83 protected static final class ProfileInfo { 84 public Map objects; 85 public SourceValidity validity; 86 } 87 88 protected ProfileInfo copletBaseDatas; 89 protected ProfileInfo copletDatas; 90 91 92 protected UserInfoProvider provider; 93 94 95 protected String userInfoProviderClassName; 96 97 98 protected Context context; 99 100 103 public void contextualize(Context context) throws ContextException { 104 this.context = context; 105 } 106 107 110 public void parameterize(Parameters params) throws ParameterException { 111 this.userInfoProviderClassName = params.getParameter("userinfo-provider"); 112 } 113 114 117 public void initialize() throws Exception { 118 this.provider = (UserInfoProvider)ClassUtils.newInstance(this.userInfoProviderClassName); 119 ContainerUtil.enableLogging(this.provider, this.getLogger()); 120 ContainerUtil.contextualize(this.provider, this.context); 121 ContainerUtil.service(this.provider, this.manager); 122 ContainerUtil.initialize(this.provider); 123 this.copletBaseDatas = new ProfileInfo(); 124 this.copletDatas = new ProfileInfo(); 125 } 126 127 130 public void dispose() { 131 ContainerUtil.dispose(this.provider); 132 this.provider = null; 133 this.manager = null; 134 } 135 136 protected UserProfile getUserProfile(String layoutKey) { 137 PortalService service = null; 138 try { 139 service = (PortalService)this.manager.lookup(PortalService.ROLE); 140 if ( layoutKey == null ) { 141 layoutKey = service.getDefaultLayoutKey(); 142 } 143 144 return (UserProfile)service.getAttribute(KEY_PREFIX + layoutKey); 145 } catch (ServiceException e) { 146 throw new CascadingRuntimeException("Unable to lookup portal service.", e); 148 } finally { 149 this.manager.release(service); 150 } 151 } 152 153 protected void removeUserProfiles() { 154 PortalService service = null; 156 try { 157 service = (PortalService)this.manager.lookup(PortalService.ROLE); 158 final String layoutKey = service.getDefaultLayoutKey(); 159 160 service.removeAttribute(KEY_PREFIX + layoutKey); 161 } catch (ServiceException e) { 162 throw new CascadingRuntimeException("Unable to lookup portal service.", e); 164 } finally { 165 this.manager.release(service); 166 } 167 } 168 169 protected void storeUserProfile(String layoutKey, PortalService service, UserProfile profile) { 170 if ( layoutKey == null ) { 171 layoutKey = service.getDefaultLayoutKey(); 172 } 173 service.setAttribute(KEY_PREFIX + layoutKey, profile); 174 } 175 176 179 protected void prepareObject(Object object, PortalService service) 180 throws ProcessingException { 181 if ( object != null ) { 182 if ( object instanceof Map ) { 183 object = ((Map )object).values(); 184 } 185 if (object instanceof Layout) { 186 service.getComponentManager().getLayoutFactory().prepareLayout((Layout)object); 187 } else if (object instanceof Collection ) { 188 ServiceSelector adapterSelector = null; 189 try { 190 final CopletFactory copletFactory = service.getComponentManager().getCopletFactory(); 191 final Iterator iterator = ((Collection )object).iterator(); 192 while (iterator.hasNext()) { 193 final Object o = iterator.next(); 194 if ( o instanceof CopletData ) { 195 copletFactory.prepare((CopletData)o); 196 } else if ( o instanceof CopletInstanceData) { 197 if ( adapterSelector == null ) { 198 adapterSelector = (ServiceSelector)this.manager.lookup(CopletAdapter.ROLE+"Selector"); 199 } 200 CopletInstanceData cid = (CopletInstanceData)o; 201 copletFactory.prepare(cid); 202 CopletAdapter adapter = null; 204 try { 205 adapter = (CopletAdapter) adapterSelector.select(cid.getCopletData().getCopletBaseData().getCopletAdapterName()); 206 adapter.login( cid ); 207 } finally { 208 adapterSelector.release( adapter ); 209 } 210 } 211 } 212 } catch (ServiceException se) { 213 throw new ProcessingException("Unable to get component.", se); 215 } finally { 216 this.manager.release(adapterSelector); 217 } 218 } 219 } 220 } 221 222 225 public void login() { 226 super.login(); 227 this.getPortalLayout(null, null); 230 } 231 232 235 public void logout() { 236 final UserProfile profile = this.getUserProfile(null); 237 if ( profile != null ) { 238 ServiceSelector adapterSelector = null; 239 try { 240 adapterSelector = (ServiceSelector)this.manager.lookup(CopletAdapter.ROLE+"Selector"); 241 242 Iterator iter = profile.getCopletInstanceDatas().values().iterator(); 243 while ( iter.hasNext() ) { 244 CopletInstanceData cid = (CopletInstanceData) iter.next(); 245 CopletAdapter adapter = null; 246 try { 247 adapter = (CopletAdapter)adapterSelector.select(cid.getCopletData().getCopletBaseData().getCopletAdapterName()); 248 adapter.logout( cid ); 249 } finally { 250 adapterSelector.release( adapter ); 251 } 252 } 253 254 } catch (ServiceException e) { 255 throw new CascadingRuntimeException("Unable to lookup portal service.", e); 256 } finally { 257 this.manager.release(adapterSelector); 258 } 259 this.removeUserProfiles(); 260 } 261 super.logout(); 262 } 263 264 267 public CopletInstanceData getCopletInstanceData(String copletID) { 268 final UserProfile profile = this.getUserProfile(null); 269 if ( profile != null ) { 270 return (CopletInstanceData)profile.getCopletInstanceDatas().get(copletID); 271 } 272 return null; 273 } 274 275 278 public CopletData getCopletData(String copletDataId) { 279 final UserProfile profile = this.getUserProfile(null); 280 if ( profile != null ) { 281 return (CopletData)profile.getCopletDatas().get(copletDataId); 282 } 283 return null; 284 } 285 286 289 public List getCopletInstanceData(CopletData data) { 290 final UserProfile profile = this.getUserProfile(null); 291 final List coplets = new ArrayList (); 292 if ( profile != null ) { 293 final Iterator iter = profile.getCopletInstanceDatas().values().iterator(); 294 while ( iter.hasNext() ) { 295 final CopletInstanceData current = (CopletInstanceData)iter.next(); 296 if ( current.getCopletData().equals(data) ) { 297 coplets.add( current ); 298 } 299 } 300 } 301 return coplets; 302 } 303 304 307 public void register(CopletInstanceData coplet) { 308 final UserProfile profile = this.getUserProfile(null); 309 profile.getCopletInstanceDatas().put(coplet.getId(), coplet); 310 } 311 312 315 public void unregister(CopletInstanceData coplet) { 316 final UserProfile profile = this.getUserProfile(null); 317 profile.getCopletInstanceDatas().remove(coplet.getId()); 318 } 319 320 323 public void register(Layout layout) { 324 if ( layout != null && layout.getId() != null ) { 325 final UserProfile profile = this.getUserProfile(null); 326 profile.getLayouts().put(layout.getId(), layout); 327 } 328 } 329 330 333 public void unregister(Layout layout) { 334 if ( layout != null && layout.getId() != null ) { 335 final UserProfile profile = this.getUserProfile(null); 336 profile.getLayouts().remove(layout.getId()); 337 } 338 } 339 340 343 public Layout getPortalLayout(String layoutKey, String layoutId) { 344 PortalService service = null; 345 346 try { 347 service = (PortalService) this.manager.lookup(PortalService.ROLE); 348 if ( null == layoutKey ) { 349 layoutKey = service.getDefaultLayoutKey(); 350 } 351 352 UserProfile profile = this.getUserProfile(layoutKey); 353 if ( profile == null ) { 354 profile = this.loadProfile(layoutKey, service); 355 } 356 if ( profile == null ) { 357 throw new RuntimeException ("Unable to load profile: " + layoutKey); 358 } 359 if ( layoutId != null ) { 360 return (Layout)profile.getLayouts().get(layoutId); 361 } 362 return profile.getRootLayout(); 363 } catch (Exception ce) { 364 throw new CascadingRuntimeException("Exception during loading of profile.", ce); 365 } finally { 366 this.manager.release(service); 367 } 368 } 369 370 373 public Collection getCopletDatas() { 374 final UserProfile profile = this.getUserProfile(null); 375 if ( profile != null ) { 376 return profile.getCopletDatas().values(); 377 } 378 return null; 379 } 380 381 384 public Collection getCopletInstanceDatas() { 385 final UserProfile profile = this.getUserProfile(null); 386 if ( profile != null ) { 387 return profile.getCopletInstanceDatas().values(); 388 } 389 return null; 390 } 391 392 395 protected UserProfile loadProfile(final String layoutKey, final PortalService service) 396 throws Exception { 397 final UserInfo info = this.provider.getUserInfo(service.getPortalName(), layoutKey); 398 ProfileLS loader = null; 399 try { 400 loader = (ProfileLS)this.manager.lookup( ProfileLS.ROLE ); 401 final UserProfile profile = new UserProfile(); 402 this.storeUserProfile(layoutKey, service, profile); 403 404 profile.setCopletBaseDatas( this.getGlobalBaseDatas(loader, info, service) ); 406 profile.setCopletDatas( this.getGlobalDatas(loader, info, service, profile) ); 407 408 if ( !this.getCopletInstanceDatas(loader, profile, info, service, CATEGORY_USER) ) { 410 if ( info.getGroup() == null || !this.getCopletInstanceDatas(loader, profile, info, service, CATEGORY_GROUP)) { 411 if ( !this.getCopletInstanceDatas(loader, profile, info, service, CATEGORY_GLOBAL) ) { 412 throw new ProcessingException("No profile for copletinstancedatas found."); 413 } 414 } 415 } 416 417 if ( !this.getLayout(loader, profile, info, service, CATEGORY_USER) ) { 418 if ( info.getGroup() == null || !this.getLayout(loader, profile, info, service, CATEGORY_GROUP)) { 419 if ( !this.getLayout(loader, profile, info, service, CATEGORY_GLOBAL) ) { 420 throw new ProcessingException("No profile for layout found."); 421 } 422 } 423 } 424 425 return profile; 426 } catch (ServiceException se) { 427 throw new CascadingRuntimeException("Unable to get component profilels.", se); 428 } finally { 429 this.manager.release( loader ); 430 } 431 } 432 433 protected Map getGlobalBaseDatas(final ProfileLS loader, 434 final UserInfo info, 435 final PortalService service) 436 throws Exception { 437 synchronized ( this ) { 438 final Map key = this.buildKey(CATEGORY_GLOBAL, 439 ProfileLS.PROFILETYPE_COPLETBASEDATA, 440 info, 441 true); 442 final Map parameters = new HashMap (); 443 parameters.put(ProfileLS.PARAMETER_PROFILETYPE, 444 ProfileLS.PROFILETYPE_COPLETBASEDATA); 445 446 if ( this.copletBaseDatas.validity != null 447 && this.copletBaseDatas.validity.isValid() == SourceValidity.VALID) { 448 return this.copletBaseDatas.objects; 449 } 450 final SourceValidity newValidity = loader.getValidity(key, parameters); 451 if ( this.copletBaseDatas.validity != null 452 && newValidity != null 453 && this.copletBaseDatas.validity.isValid(newValidity) == SourceValidity.VALID) { 454 return this.copletBaseDatas.objects; 455 } 456 this.copletBaseDatas.objects = ((CopletBaseDataManager)loader.loadProfile(key, parameters)).getCopletBaseData(); 457 this.copletBaseDatas.validity = newValidity; 458 this.copletDatas.objects = null; 459 this.copletDatas.validity = null; 460 this.prepareObject(this.copletBaseDatas.objects, service); 461 return this.copletBaseDatas.objects; 462 } 463 } 464 465 protected Map getGlobalDatas(final ProfileLS loader, 466 final UserInfo info, 467 final PortalService service, 468 final UserProfile profile) 469 throws Exception { 470 synchronized ( this ) { 471 final Map key = this.buildKey(CATEGORY_GLOBAL, 472 ProfileLS.PROFILETYPE_COPLETDATA, 473 info, 474 true); 475 final Map parameters = new HashMap (); 476 parameters.put(ProfileLS.PARAMETER_PROFILETYPE, 477 ProfileLS.PROFILETYPE_COPLETDATA); 478 parameters.put(ProfileLS.PARAMETER_OBJECTMAP, 479 profile.getCopletBaseDatas()); 480 481 if ( this.copletDatas.validity != null 482 && this.copletDatas.validity.isValid() == SourceValidity.VALID) { 483 return this.copletDatas.objects; 484 } 485 final SourceValidity newValidity = loader.getValidity(key, parameters); 486 if ( this.copletDatas.validity != null 487 && newValidity != null 488 && this.copletDatas.validity.isValid(newValidity) == SourceValidity.VALID) { 489 return this.copletDatas.objects; 490 } 491 this.copletDatas.objects = ((CopletDataManager)loader.loadProfile(key, parameters)).getCopletData(); 492 this.copletDatas.validity = newValidity; 493 this.prepareObject(this.copletDatas.objects, service); 494 return this.copletDatas.objects; 495 } 496 } 497 498 private boolean isSourceNotFoundException(Throwable t) { 499 while (t != null) { 500 if (t instanceof SourceNotFoundException) { 501 return true; 502 } 503 t = ExceptionUtils.getCause(t); 504 } 505 return false; 506 } 507 508 protected boolean getCopletInstanceDatas(final ProfileLS loader, 509 final UserProfile profile, 510 final UserInfo info, 511 final PortalService service, 512 final String category) 513 throws Exception { 514 Map key = this.buildKey(category, 515 ProfileLS.PROFILETYPE_COPLETINSTANCEDATA, 516 info, 517 true); 518 Map parameters = new HashMap (); 519 parameters.put(ProfileLS.PARAMETER_PROFILETYPE, 520 ProfileLS.PROFILETYPE_COPLETINSTANCEDATA); 521 parameters.put(ProfileLS.PARAMETER_OBJECTMAP, 522 profile.getCopletDatas()); 523 524 try { 525 CopletInstanceDataManager cidm = (CopletInstanceDataManager)loader.loadProfile(key, parameters); 526 profile.setCopletInstanceDatas(cidm.getCopletInstanceData()); 527 this.prepareObject(profile.getCopletInstanceDatas(), service); 528 529 return true; 530 } catch (Exception e) { 531 if (!isSourceNotFoundException(e)) { 532 throw e; 533 } 534 return false; 535 } 536 } 537 538 protected boolean getLayout(final ProfileLS loader, 539 final UserProfile profile, 540 final UserInfo info, 541 final PortalService service, 542 final String category) 543 throws Exception { 544 final Map key = this.buildKey(category, 545 ProfileLS.PROFILETYPE_LAYOUT, 546 info, 547 true); 548 final Map parameters = new HashMap (); 549 parameters.put(ProfileLS.PARAMETER_PROFILETYPE, 550 ProfileLS.PROFILETYPE_LAYOUT); 551 parameters.put(ProfileLS.PARAMETER_OBJECTMAP, 552 profile.getCopletInstanceDatas()); 553 try { 554 Layout l = (Layout)loader.loadProfile(key, parameters); 555 this.prepareObject(l, service); 556 profile.setRootLayout(l); 557 558 return true; 559 } catch (Exception e) { 560 if (!isSourceNotFoundException(e)) { 561 throw e; 562 } 563 return false; 564 } 565 } 566 567 protected Map buildKey(String category, 568 String profileType, 569 UserInfo info, 570 boolean load) { 571 final StringBuffer config = new StringBuffer (profileType); 572 config.append('-'); 573 config.append(category); 574 config.append('-'); 575 if ( load ) { 576 config.append("load"); 577 } else { 578 config.append("save"); 579 } 580 final String uri = (String )info.getConfigurations().get(config.toString()); 581 582 final Map key = new LinkedMap(); 583 key.put("baseuri", uri); 584 key.put("separator", "?"); 585 key.put("portal", info.getPortalName()); 586 key.put("layout", info.getLayoutKey()); 587 key.put("type", category); 588 if ( "group".equals(category) ) { 589 key.put("group", info.getGroup()); 590 } 591 if ( "user".equals(category) ) { 592 key.put("user", info.getUserName()); 593 } 594 595 return key; 596 } 597 598 599 602 public void storeProfile(Layout rootLayout, String layoutKey) { 603 PortalService service = null; 604 605 try { 606 UserProfile oldProfile = this.getUserProfile(null); 607 service = (PortalService) this.manager.lookup(PortalService.ROLE); 608 if ( null == layoutKey ) { 609 layoutKey = service.getDefaultLayoutKey(); 610 } 611 UserProfile newProfile = new UserProfile(); 613 newProfile.setCopletBaseDatas(oldProfile.getCopletBaseDatas()); 614 newProfile.setCopletDatas(oldProfile.getCopletDatas()); 615 newProfile.setCopletInstanceDatas(oldProfile.getCopletInstanceDatas()); 616 newProfile.setRootLayout(rootLayout); 617 618 this.storeUserProfile(layoutKey, service, newProfile); 619 } catch (Exception ce) { 620 throw new CascadingRuntimeException("Exception during loading of profile.", ce); 621 } finally { 622 this.manager.release(service); 623 } 624 } 625 626 627 630 public PortalUser getUser() { 631 PortalService service = null; 632 try { 633 service = (PortalService) this.manager.lookup(PortalService.ROLE); 634 final String layoutKey = service.getDefaultLayoutKey(); 635 final UserInfo info = this.provider.getUserInfo(service.getPortalName(), layoutKey); 636 return info; 637 } catch (Exception ce) { 638 throw new CascadingRuntimeException("Exception during getUser().", ce); 639 } finally { 640 this.manager.release(service); 641 } 642 } 643 644 647 public void saveUserCopletInstanceDatas(String layoutKey) { 648 ProfileLS adapter = null; 649 PortalService service = null; 650 try { 651 service = (PortalService) this.manager.lookup(PortalService.ROLE); 652 adapter = (ProfileLS) this.manager.lookup(ProfileLS.ROLE); 653 if (layoutKey == null) { 654 layoutKey = service.getDefaultLayoutKey(); 655 } 656 final UserProfile profile = this.getUserProfile(layoutKey); 657 658 final Map parameters = new HashMap (); 659 parameters.put(ProfileLS.PARAMETER_PROFILETYPE, 660 ProfileLS.PROFILETYPE_COPLETINSTANCEDATA); 661 662 final UserInfo info = this.provider.getUserInfo(service.getPortalName(), layoutKey); 663 final Map key = this.buildKey(CATEGORY_USER, 664 ProfileLS.PROFILETYPE_COPLETINSTANCEDATA, 665 info, 666 false); 667 CopletInstanceDataManager cidm = new CopletInstanceDataManager(profile.getCopletInstanceDatas()); 669 adapter.saveProfile(key, parameters, cidm); 670 } catch (Exception e) { 671 throw new CascadingRuntimeException("Exception during save profile", e); 673 } finally { 674 this.manager.release(service); 675 this.manager.release(adapter); 676 } 677 } 678 679 682 public void saveUserLayout(String layoutKey) { 683 ProfileLS adapter = null; 684 PortalService service = null; 685 try { 686 service = (PortalService) this.manager.lookup(PortalService.ROLE); 687 adapter = (ProfileLS) this.manager.lookup(ProfileLS.ROLE); 688 if (layoutKey == null) { 689 layoutKey = service.getDefaultLayoutKey(); 690 } 691 final UserProfile profile = this.getUserProfile(layoutKey); 692 693 final Map parameters = new HashMap (); 694 parameters.put(ProfileLS.PARAMETER_PROFILETYPE, 695 ProfileLS.PROFILETYPE_LAYOUT); 696 697 final UserInfo info = this.provider.getUserInfo(service.getPortalName(), layoutKey); 698 final Map key = this.buildKey(CATEGORY_USER, 699 ProfileLS.PROFILETYPE_LAYOUT, 700 info, 701 false); 702 adapter.saveProfile(key, parameters, profile.getRootLayout()); 703 } catch (Exception e) { 704 throw new CascadingRuntimeException("Exception during save profile", e); 706 } finally { 707 this.manager.release(service); 708 this.manager.release(adapter); 709 } 710 } 711 } 712 | Popular Tags |