1 16 package org.apache.cocoon.portal.profile.impl; 17 18 import java.io.Serializable ; 19 import java.util.HashMap ; 20 import java.util.HashSet ; 21 import java.util.Iterator ; 22 import java.util.Map ; 23 24 import org.apache.avalon.framework.CascadingRuntimeException; 25 import org.apache.avalon.framework.configuration.Configuration; 26 import org.apache.avalon.framework.configuration.ConfigurationException; 27 import org.apache.avalon.framework.service.ServiceException; 28 import org.apache.avalon.framework.service.ServiceSelector; 29 import org.apache.cocoon.ProcessingException; 30 import org.apache.cocoon.portal.PortalService; 31 import org.apache.cocoon.portal.coplet.CopletFactory; 32 import org.apache.cocoon.portal.coplet.CopletInstanceData; 33 import org.apache.cocoon.portal.coplet.adapter.CopletAdapter; 34 import org.apache.cocoon.portal.layout.Layout; 35 import org.apache.cocoon.portal.layout.LayoutFactory; 36 import org.apache.cocoon.portal.profile.PortalUser; 37 import org.apache.cocoon.portal.profile.ProfileLS; 38 import org.apache.cocoon.portal.util.DeltaApplicableReferencesAdjustable; 39 import org.apache.cocoon.portal.util.ProfileException; 40 import org.apache.cocoon.webapps.authentication.AuthenticationManager; 41 import org.apache.cocoon.webapps.authentication.configuration.ApplicationConfiguration; 42 import org.apache.cocoon.webapps.authentication.user.RequestState; 43 import org.apache.cocoon.webapps.authentication.user.UserHandler; 44 import org.apache.commons.collections.map.LinkedMap; 45 import org.apache.commons.lang.exception.ExceptionUtils; 46 import org.apache.excalibur.source.SourceNotFoundException; 47 import org.apache.excalibur.source.SourceValidity; 48 49 57 public class AuthenticationProfileManager 58 extends AbstractUserProfileManager { 59 60 protected ReadWriteLock lock = new ReadWriteLock(); 61 62 protected Map attributes = new HashMap (); 63 64 68 protected RequestState getRequestState() { 69 AuthenticationManager authManager = null; 70 try { 71 authManager = (AuthenticationManager)this.manager.lookup(AuthenticationManager.ROLE); 72 return authManager.getState(); 73 } catch (ServiceException ce) { 74 return null; 76 } finally { 77 this.manager.release( authManager ); 78 } 79 } 80 81 84 protected Layout loadProfile(String layoutKey, 85 PortalService service, 86 CopletFactory copletFactory, 87 LayoutFactory layoutFactory, 88 ServiceSelector adapterSelector) 89 throws Exception { 90 final RequestState state = this.getRequestState(); 91 final UserHandler handler = state.getHandler(); 92 final ApplicationConfiguration ac = state.getApplicationConfiguration(); 93 if ( ac == null ) { 94 throw new ProcessingException("Configuration for portal not found in application configuration."); 95 } 96 final Configuration appConf = ac.getConfiguration("portal"); 97 if ( appConf == null ) { 98 throw new ProcessingException("Configuration for portal not found in application configuration."); 99 } 100 final Configuration config = appConf.getChild("profiles"); 101 102 HashMap parameters = new HashMap (); 103 parameters.put("config", config); 104 parameters.put("handler", handler); 105 CopletDataManager copletDataManager = null; 106 try { 107 this.lock.readLock(); 108 109 parameters.put("profiletype", "copletbasedata"); 111 parameters.put("objectmap", null); 112 113 Object [] result = this.getProfile(layoutKey, parameters, null, false, service); 114 CopletBaseDataManager copletBaseDataManager = (CopletBaseDataManager)result[0]; 115 116 parameters.put("profiletype", "copletdata"); 118 parameters.put("objectmap", copletBaseDataManager.getCopletBaseData()); 119 copletDataManager = (CopletDataManager)this.getDeltaProfile(layoutKey, parameters, service, copletFactory, ((Boolean )result[1]).booleanValue()); 120 service.setAttribute("CopletData:" + layoutKey, copletDataManager); 121 } finally { 122 this.lock.releaseLocks(); 123 } 124 parameters.put("profiletype", "copletinstancedata"); 126 parameters.put("objectmap", copletDataManager.getCopletData()); 127 CopletInstanceDataManager copletInstanceDataManager = (CopletInstanceDataManager)this.getOrCreateProfile(layoutKey, parameters, service, copletFactory); 128 service.setAttribute("CopletInstanceData:" + layoutKey, copletInstanceDataManager); 129 130 parameters.put("profiletype", "layout"); 132 parameters.put("objectmap", copletInstanceDataManager.getCopletInstanceData()); 133 Layout layout = (Layout)this.getOrCreateProfile(layoutKey, parameters, service, layoutFactory); 134 service.setAttribute("Layout:" + layoutKey, layout); 135 136 Iterator iter = copletInstanceDataManager.getCopletInstanceData().values().iterator(); 138 while ( iter.hasNext() ) { 139 CopletInstanceData cid = (CopletInstanceData) iter.next(); 140 CopletAdapter adapter = null; 141 try { 142 adapter = (CopletAdapter) adapterSelector.select(cid.getCopletData().getCopletBaseData().getCopletAdapterName()); 143 adapter.login( cid ); 144 } finally { 145 adapterSelector.release( adapter ); 146 } 147 } 148 149 return layout; 150 } 151 152 155 public void saveUserCopletInstanceDatas(String layoutKey) { 156 ProfileLS adapter = null; 157 PortalService service = null; 158 try { 159 adapter = (ProfileLS) this.manager.lookup(ProfileLS.ROLE); 160 service = (PortalService) this.manager.lookup(PortalService.ROLE); 161 if (layoutKey == null) { 162 layoutKey = service.getDefaultLayoutKey(); 163 } 164 165 final RequestState state = this.getRequestState(); 166 final UserHandler handler = state.getHandler(); 167 168 final HashMap parameters = new HashMap (); 169 parameters.put("type", "user"); 170 parameters.put("config", state.getApplicationConfiguration().getConfiguration("portal").getChild("profiles")); 171 parameters.put("handler", handler); 172 parameters.put("profiletype", "copletinstancedata"); 173 174 final Map key = this.buildKey(service, parameters, layoutKey, false); 175 176 final CopletInstanceDataManager profileManager = ((CopletInstanceDataManager) service.getAttribute("CopletInstanceData:" + 177 layoutKey)); 178 adapter.saveProfile(key, parameters, profileManager); 179 } catch (Exception e) { 180 throw new CascadingRuntimeException("Exception during save profile", e); 182 } finally { 183 this.manager.release(adapter); 184 this.manager.release(service); 185 } 186 } 187 188 191 public void saveUserLayout(String layoutKey) { 192 ProfileLS adapter = null; 193 PortalService service = null; 194 try { 195 adapter = (ProfileLS) this.manager.lookup(ProfileLS.ROLE); 196 service = (PortalService) this.manager.lookup(PortalService.ROLE); 197 if ( layoutKey == null ) { 198 layoutKey = service.getDefaultLayoutKey(); 199 } 200 201 final RequestState state = this.getRequestState(); 202 final UserHandler handler = state.getHandler(); 203 204 final HashMap parameters = new HashMap (); 205 parameters.put("type", "user"); 206 parameters.put("config", state.getApplicationConfiguration().getConfiguration("portal").getChild("profiles")); 207 parameters.put("handler", handler); 208 parameters.put("profiletype", "layout"); 209 210 final Map key = this.buildKey(service, parameters, layoutKey, false); 211 final Layout layout = (Layout)service.getAttribute("Layout:" + layoutKey); 212 adapter.saveProfile(key, parameters, layout); 213 214 } catch (Exception e) { 215 throw new CascadingRuntimeException("Exception during save profile", e); 217 } finally { 218 this.manager.release(adapter); 219 this.manager.release(service); 220 } 221 } 222 223 226 protected Object getDeltaProfile(String layoutKey, 227 Map parameters, 228 PortalService service, 229 Object factory, 230 boolean forcedLoad) 231 throws Exception { 232 DeltaApplicableReferencesAdjustable result; 233 Object object; 234 235 parameters.put("type", "global"); 236 Object global = this.getProfile(layoutKey, parameters, factory, forcedLoad, service)[0]; 237 Object key = this.buildKey(service, parameters, layoutKey, true); 238 result = (DeltaApplicableReferencesAdjustable)this.loadProfile(key, parameters, factory); 239 240 parameters.put("type", "role"); 242 try { 243 object = this.getProfile(layoutKey, parameters, factory, forcedLoad, service)[0]; 244 if (object != null) 245 result.applyDelta(object); 246 } catch (Exception e) { 247 if (!isSourceNotFoundException(e)) 248 throw e; 249 } 250 251 parameters.put("type", "user"); 253 try { 254 key = this.buildKey(service, parameters, layoutKey, true); 255 object = this.loadProfile(key, parameters, factory); 256 if (object != null) 257 result.applyDelta(object); 258 } catch (Exception e) { 259 if (!isSourceNotFoundException(e)) 260 throw e; 261 } 262 263 if (result == null) 264 throw new SourceNotFoundException("Global profile does not exist."); 265 266 result.adjustReferences(global); 268 269 this.attributes.put(key, result); 271 272 return result; 273 } 274 275 278 protected Object getOrCreateProfile(String layoutKey, Map parameters, PortalService service, Object factory) 279 throws Exception { 280 Object result; 281 282 parameters.put("type", "user"); 284 Map keyMap = this.buildKey(service, parameters, layoutKey, true); 285 try { 286 result = this.loadProfile(keyMap, parameters, factory); 287 } catch (Exception e1) { 288 if (!isSourceNotFoundException(e1)) 289 throw e1; 290 291 parameters.put("type", "role"); 293 keyMap = this.buildKey(service, parameters, layoutKey, true); 294 try { 295 result = this.loadProfile(keyMap, parameters, factory); 296 } catch (Exception e2) { 297 if (!isSourceNotFoundException(e2)) 298 throw e2; 299 300 parameters.put("type", "global"); 302 keyMap = this.buildKey(service, parameters, layoutKey, true); 303 result = this.loadProfile(keyMap, parameters, factory); 304 } 305 306 ProfileLS adapter = null; 308 try { 309 adapter = (ProfileLS) this.manager.lookup(ProfileLS.ROLE); 310 parameters.put("type", "user"); 311 keyMap = this.buildKey(service, parameters, layoutKey, false); 312 313 } finally { 315 this.manager.release(adapter); 316 } 317 } 318 319 this.attributes.put(keyMap, result); 321 322 return result; 323 } 324 325 330 protected Object [] getProfile(String layoutKey, 331 Map parameters, 332 Object factory, 333 boolean forcedLoad, 334 PortalService service) 335 throws Exception { 336 final Map key = this.buildKey(service, parameters, layoutKey, true); 337 338 ProfileLS adapter = null; 339 try { 340 adapter = (ProfileLS)this.manager.lookup(ProfileLS.ROLE); 341 342 Object result = this.checkValidity(key, parameters, forcedLoad, adapter); 343 344 if ( result != null && !(result instanceof SourceValidity)) { 345 return new Object []{result, Boolean.FALSE}; 346 } 347 SourceValidity newValidity = (SourceValidity)result; 348 349 this.lock.releaseReadLock(); 350 this.lock.writeLock(); 351 352 result = this.checkValidity(key, parameters, forcedLoad, adapter); 354 355 if ( result != null && !(result instanceof SourceValidity) ) { 356 return new Object []{result, Boolean.FALSE}; 357 } 358 newValidity = (SourceValidity)result; 359 360 Object object = adapter.loadProfile(key, parameters); 361 this.prepareObject(object, factory); 362 if (newValidity != null) { 363 this.attributes.put(key, new Object [] {object, newValidity}); 364 } 365 366 return new Object [] {object, Boolean.TRUE}; 367 } catch (SourceNotFoundException se) { 368 this.getLogger().warn("Unable to locate profile: " + se.getMessage()); 369 throw se; 370 } catch (ProfileException pe) { 371 this.getLogger().error("Error loading profile: " + pe.getMessage(), pe); 372 throw pe; 373 } catch (Exception t) { 374 this.getLogger().error("Error loading profile.", t); 375 throw t; 376 } finally { 377 this.manager.release(adapter); 378 } 379 } 380 381 384 protected Object checkValidity(Object key, 385 Map parameters, 386 boolean forcedLoad, 387 ProfileLS adapter) { 388 Object [] objects = (Object [])this.attributes.get(key); 389 390 SourceValidity sourceValidity = null; 391 int valid = SourceValidity.INVALID; 392 if (objects != null) { 393 sourceValidity = (SourceValidity) objects[1]; 394 valid = sourceValidity.isValid(); 395 if (!forcedLoad && valid == SourceValidity.VALID) 396 return objects[0]; 397 } 398 399 SourceValidity newValidity = adapter.getValidity(key, parameters); 400 if (!forcedLoad && valid == SourceValidity.UNKNOWN) { 401 if (sourceValidity.isValid(newValidity) == SourceValidity.VALID) 402 return objects[0]; 403 } 404 405 return newValidity; 406 } 407 408 411 protected Object loadProfile(Object key, Map map, Object factory) 412 throws Exception { 413 ProfileLS adapter = null; 414 try { 415 adapter = (ProfileLS) this.manager.lookup(ProfileLS.ROLE); 416 417 Object object = adapter.loadProfile(key, map); 418 this.prepareObject(object, factory); 419 420 return object; 421 } finally { 422 this.manager.release(adapter); 423 } 424 } 425 426 private boolean isSourceNotFoundException(Throwable t) { 427 while (t != null) { 428 if (t instanceof SourceNotFoundException) { 429 return true; 430 } 431 t = ExceptionUtils.getCause(t); 432 } 433 return false; 434 } 435 436 protected Map buildKey(PortalService service, 437 Map parameters, 438 String layoutKey, 439 boolean load) 440 throws ProcessingException, ConfigurationException { 441 442 final String type = (String )parameters.get("type"); 444 final Configuration config = (Configuration) parameters.get("config"); 445 final String profileType = (String )parameters.get("profiletype"); 446 final String postFix = (load ? "load" : "save"); 447 final UserHandler handler = (UserHandler)parameters.get("handler"); 448 449 String uri = null; 450 if (type == null) { 451 uri = config.getChild(profileType + "-" + postFix).getAttribute("uri"); 452 } else if (type.equals("global")) { 453 uri = config.getChild(profileType + "-global-" + postFix).getAttribute("uri"); 454 } else if (type.equals("role")) { 455 uri = config.getChild(profileType + "-role-" + postFix).getAttribute("uri"); 456 } else if (type.equals("user")) { 457 uri = config.getChild(profileType + "-user-" + postFix).getAttribute("uri"); 458 } 459 460 Map key = new LinkedMap(); 461 key.put("baseuri", uri); 462 key.put("separator", "?"); 463 key.put("portal", service.getPortalName()); 464 key.put("layout", layoutKey); 465 if ( type != null ) { 466 key.put("type", type); 467 if ( "role".equals(type) || "user".equals(type)) { 468 key.put("role", handler.getContext().getContextInfo().get("role")); 469 } 470 if ( "user".equals(type) ) { 471 key.put("user", handler.getUserId()); 472 } 473 } 474 return key; 475 } 476 477 static class ReadWriteLock { 478 private Thread activeWriter = null; 479 private HashSet activeReaders = new HashSet (); 480 private int waitingWriters = 0; 481 482 public void readLock() 483 throws InterruptedException { 484 synchronized (ReadWriteLock.this) { 485 while (this.activeWriter != null || this.waitingWriters != 0) { 486 ReadWriteLock.this.wait(); 487 } 488 this.activeReaders.add(Thread.currentThread()); 489 } 490 } 491 492 public void writeLock() 493 throws InterruptedException { 494 synchronized (ReadWriteLock.this) { 495 Thread current = Thread.currentThread(); 496 497 if (this.activeWriter != current) { 498 this.waitingWriters++; 499 while (this.activeWriter != null || this.activeReaders.size() != 0) { 500 ReadWriteLock.this.wait(); 501 } 502 this.waitingWriters--; 503 this.activeWriter = current; 504 } 505 } 506 } 507 508 public void releaseReadLock() { 509 synchronized (ReadWriteLock.this) { 510 Thread current = Thread.currentThread(); 511 512 this.activeReaders.remove(current); 513 if (this.activeReaders.size() == 0 && this.waitingWriters > 0) { 514 ReadWriteLock.this.notifyAll(); 515 } 516 } 517 } 518 519 public void releaseLocks() { 520 synchronized (ReadWriteLock.this) { 521 Thread current = Thread.currentThread(); 522 boolean notify = false; 523 524 if (this.activeWriter == current) { 525 this.activeWriter = null; 526 notify = true; 527 } 528 529 this.activeReaders.remove(current); 530 if (this.activeReaders.size() == 0 && this.waitingWriters > 0) { 531 notify = true; 532 } 533 534 if (notify) { 535 ReadWriteLock.this.notifyAll(); 536 } 537 } 538 } 539 } 540 541 542 545 public PortalUser getUser() { 546 final RequestState state = this.getRequestState(); 547 return new User(state); 548 } 549 550 protected static final class User implements PortalUser, Serializable { 551 552 protected final RequestState state; 553 554 public User(RequestState state) { 555 this.state = state; 556 } 557 558 561 public String getGroup() { 562 return null; 564 } 565 566 569 public String getUserName() { 570 return this.state.getHandler().getUserId(); 571 } 572 573 576 public boolean isUserInRole(String role) { 577 return this.state.getHandler().isUserInRole(role); 578 } 579 } 580 581 } 582 | Popular Tags |