| 1 16 package org.apache.cocoon.webapps.portal.components; 17 18 import java.io.IOException ; 19 import java.util.ArrayList ; 20 import java.util.Enumeration ; 21 import java.util.HashMap ; 22 import java.util.Iterator ; 23 import java.util.List ; 24 import java.util.Map ; 25 26 import org.apache.avalon.excalibur.pool.Recyclable; 27 import org.apache.avalon.framework.activity.Disposable; 28 import org.apache.avalon.framework.component.Component; 29 import org.apache.avalon.framework.component.ComponentException; 30 import org.apache.avalon.framework.component.ComponentManager; 31 import org.apache.avalon.framework.component.Composable; 32 import org.apache.avalon.framework.component.Recomposable; 33 import org.apache.avalon.framework.configuration.Configuration; 34 import org.apache.avalon.framework.configuration.ConfigurationException; 35 import org.apache.avalon.framework.context.Context; 36 import org.apache.avalon.framework.context.ContextException; 37 import org.apache.avalon.framework.context.Contextualizable; 38 import org.apache.avalon.framework.logger.AbstractLogEnabled; 39 import org.apache.cocoon.ProcessingException; 40 import org.apache.cocoon.components.ContextHelper; 41 import org.apache.cocoon.components.sax.XMLDeserializer; 42 import org.apache.cocoon.components.source.SourceUtil; 43 import org.apache.cocoon.environment.CocoonRunnable; 44 import org.apache.cocoon.environment.Redirector; 45 import org.apache.cocoon.environment.Request; 46 import org.apache.cocoon.environment.Response; 47 import org.apache.cocoon.environment.Session; 48 import org.apache.cocoon.webapps.authentication.AuthenticationManager; 49 import org.apache.cocoon.webapps.authentication.user.RequestState; 50 import org.apache.cocoon.webapps.portal.PortalConstants; 51 import org.apache.cocoon.webapps.session.ContextManager; 52 import org.apache.cocoon.webapps.session.MediaManager; 53 import org.apache.cocoon.webapps.session.SessionManager; 54 import org.apache.cocoon.webapps.session.TransactionManager; 55 import org.apache.cocoon.webapps.session.context.SessionContext; 56 import org.apache.cocoon.webapps.session.xml.XMLUtil; 57 import org.apache.cocoon.xml.IncludeXMLConsumer; 58 import org.apache.cocoon.xml.XMLConsumer; 59 import org.apache.cocoon.xml.XMLUtils; 60 import org.apache.cocoon.xml.dom.DOMUtil; 61 import org.apache.excalibur.source.Source; 62 import org.apache.excalibur.source.SourceException; 63 import org.apache.excalibur.source.SourceParameters; 64 import org.apache.excalibur.source.SourceResolver; 65 import org.apache.excalibur.store.Store; 66 import org.apache.excalibur.xml.xpath.XPathProcessor; 67 import org.w3c.dom.Document ; 68 import org.w3c.dom.DocumentFragment ; 69 import org.w3c.dom.Element ; 70 import org.w3c.dom.NamedNodeMap ; 71 import org.w3c.dom.Node ; 72 import org.w3c.dom.NodeList ; 73 import org.w3c.dom.Text ; 74 import org.xml.sax.Attributes ; 75 import org.xml.sax.SAXException ; 76 import org.xml.sax.helpers.AttributesImpl ; 77 78 84 public final class PortalManagerImpl 85 extends AbstractLogEnabled 86 implements Disposable, Composable, Recomposable, Recyclable, Contextualizable, Component, PortalManager { 87 88 89 private Store profileStore; 90 91 92 private AuthenticationManager authenticationManager; 93 94 95 private MediaManager mediaManager; 96 97 98 private XPathProcessor xpathProcessor; 99 100 101 private SessionManager sessionManager; 102 103 104 private ContextManager contextManager; 105 106 107 private TransactionManager transactionManager; 108 109 110 protected ComponentManager manager; 111 112 113 protected SourceResolver resolver; 114 115 116 protected Context componentContext; 117 118 119 protected boolean initialized = false; 120 121 124 public void recycle() { 125 if (this.manager != null) { 126 this.manager.release(this.profileStore); 127 this.manager.release( (Component)this.authenticationManager); 128 this.manager.release( (Component)this.mediaManager); 129 this.manager.release( (Component)this.sessionManager); 130 this.manager.release( (Component)this.contextManager); 131 this.manager.release( (Component)this.transactionManager); 132 this.profileStore = null; 133 this.authenticationManager = null; 134 this.mediaManager = null; 135 this.transactionManager = null; 136 this.sessionManager = null; 137 this.contextManager = null; 138 } 139 this.initialized = false; 140 } 141 142 145 protected RequestState getRequestState() { 146 AuthenticationManager authManager = null; 147 try { 148 authManager = (AuthenticationManager)this.manager.lookup(AuthenticationManager.ROLE); 149 return authManager.getState(); 150 } catch (ComponentException ce) { 151 return null; 153 } finally { 154 this.manager.release( (Component)authManager ); 155 } 156 } 157 158 161 public void compose(ComponentManager manager) 162 throws ComponentException { 163 this.manager = manager; 164 this.resolver = (SourceResolver)manager.lookup(SourceResolver.ROLE); 165 this.xpathProcessor = (XPathProcessor)this.manager.lookup(XPathProcessor.ROLE); 166 } 167 168 171 public void recompose(ComponentManager manager) throws ComponentException { 172 this.manager = manager; 173 } 174 175 178 public void dispose() { 179 if ( this.manager != null ) { 180 this.manager.release( (Component)this.xpathProcessor ); 181 this.xpathProcessor = null; 182 this.manager.release( this.resolver ); 183 this.resolver = null; 184 } 185 } 186 187 190 public void contextualize(Context context) throws ContextException { 191 this.componentContext = context; 192 } 193 194 197 protected Store getProfileStore() 198 throws ProcessingException { 199 if (this.profileStore == null) { 200 try { 201 this.profileStore = (Store)this.manager.lookup(Store.ROLE); 202 } catch (ComponentException ce) { 203 throw new ProcessingException("Error during lookup of store component.", ce); 204 } 205 } 206 return this.profileStore; 207 } 208 209 212 protected AuthenticationManager getAuthenticationManager() 213 throws ProcessingException { 214 if (this.authenticationManager == null) { 215 try { 216 this.authenticationManager = (AuthenticationManager)this.manager.lookup(AuthenticationManager.ROLE); 217 } catch (ComponentException ce) { 218 throw new ProcessingException("Error during lookup of AuthenticationManager.", ce); 219 } 220 } 221 return this.authenticationManager; 222 } 223 224 227 protected MediaManager getMediaManager() 228 throws ProcessingException { 229 if (this.mediaManager == null) { 230 try { 231 this.mediaManager = (MediaManager)this.manager.lookup(MediaManager.ROLE); 232 } catch (ComponentException ce) { 233 throw new ProcessingException("Error during lookup of MediaManager.", ce); 234 } 235 } 236 return this.mediaManager; 237 } 238 239 242 protected void setup() 243 throws ProcessingException { 244 if ( !this.initialized ) { 245 246 final Request request = ContextHelper.getRequest(this.componentContext); 247 248 if ( request.getAttribute(PortalManager.ROLE) == null ) { 249 250 request.setAttribute(PortalManager.ROLE, Boolean.TRUE); 251 252 this.getConfiguration(); 254 255 try { 256 this.changeProfile(); 257 } catch (SAXException se) { 258 throw new ProcessingException(se); 259 } catch (IOException ioe) { 260 throw new ProcessingException(ioe); 261 } 262 } 263 264 this.initialized = true; 265 } 266 } 267 268 271 public void configurationTest() 272 throws ProcessingException, IOException , SAXException { 273 if (this.getLogger().isDebugEnabled()) { 275 this.getLogger().debug("BEGIN configurationTest"); 276 } 277 278 this.setup(); 279 280 this.getConfiguration(); 282 283 if (this.getLogger().isDebugEnabled()) { 284 this.getLogger().debug("END configurationTest"); 285 } 286 } 287 288 291 public SessionContext getContext(boolean create) 292 throws ProcessingException, IOException , SAXException { 293 if (this.getLogger().isDebugEnabled()) { 295 this.getLogger().debug("BEGIN getContext create="+create); 296 } 297 this.setup(); 298 SessionContext context = null; 299 300 final Session session = this.getSessionManager().getSession(false); 301 if (session != null) { 302 synchronized(session) { 303 String appName = this.getRequestState().getApplicationName(); 304 String attrName = PortalConstants.PRIVATE_SESSION_CONTEXT_NAME; 305 if (appName != null) { 306 attrName = attrName + ':' + appName; 307 } 308 context = this.getContextManager().getContext(attrName); 309 if (context == null && create) { 310 311 313 context = this.getAuthenticationManager().createApplicationContext(attrName, null, null); 314 315 } 316 } } 318 319 if (this.getLogger().isDebugEnabled()) { 320 this.getLogger().debug("END getContext context="+context); 321 } 322 return context; 323 } 324 325 328 public void streamConfiguration(XMLConsumer consumer, 329 String requestURI, 330 String profileID, 331 String media, 332 String contextID) 333 throws IOException , SAXException , ProcessingException { 334 this.setup(); 336 Response response = ContextHelper.getResponse(this.componentContext); 337 338 XMLUtils.startElement(consumer, PortalConstants.ELEMENT_CONFIGURATION); 339 340 StringBuffer buffer = new StringBuffer (requestURI); 342 buffer.append((requestURI.indexOf('?') == -1 ? '?' : '&')) 343 .append(PortalManagerImpl.REQ_PARAMETER_PROFILE) 344 .append('=') 345 .append(profileID); 346 String uri = response.encodeURL(buffer.toString()); 347 XMLUtils.startElement(consumer, "uri"); 348 XMLUtils.data(consumer, uri); 349 XMLUtils.endElement(consumer, "uri"); 350 351 Map config = this.getConfiguration(); 352 String portalURI = response.encodeURL((String )config.get(PortalConstants.CONF_PORTAL_URI)); 353 354 XMLUtils.startElement(consumer, "portal"); 355 XMLUtils.data(consumer, portalURI); 356 XMLUtils.endElement(consumer, "portal"); 357 358 XMLUtils.startElement(consumer, PortalConstants.ELEMENT_PROFILE); 359 XMLUtils.data(consumer, profileID); 360 XMLUtils.endElement(consumer, PortalConstants.ELEMENT_PROFILE); 361 362 if (media != null) { 363 XMLUtils.startElement(consumer, "media"); 364 XMLUtils.data(consumer, media); 365 XMLUtils.endElement(consumer, "media"); 366 } 367 368 if (contextID != null) { 369 XMLUtils.startElement(consumer, "context"); 370 XMLUtils.data(consumer, contextID); 371 XMLUtils.endElement(consumer, "context"); 372 } 373 374 XMLUtils.endElement(consumer, PortalConstants.ELEMENT_CONFIGURATION); 375 } 376 377 380 public void showAdminConf(XMLConsumer consumer) 381 throws SAXException , ProcessingException, IOException { 382 if (this.getLogger().isDebugEnabled()) { 384 this.getLogger().debug("BEGIN showAdminConf consumer=" + consumer); 385 } 386 this.setup(); 387 Request request = ContextHelper.getRequest(this.componentContext); 388 try { 389 String profileID = "global"; 390 String copletID = request.getParameter(PortalManagerImpl.REQ_PARAMETER_COPLET); 391 392 SessionContext context = this.getContext(true); 393 394 Map configuration = this.getConfiguration(); 395 396 DocumentFragment copletsFragment = (DocumentFragment )context.getAttribute(ATTRIBUTE_ADMIN_COPLETS); 397 String command = request.getParameter(PortalManagerImpl.REQ_PARAMETER_ADMIN_COPLETS); 398 if (command != null && copletsFragment != null) { 399 try { 400 this.getTransactionManager().startWritingTransaction(context); 401 if (command.equals("delete") && copletID != null) { 407 Node coplet = DOMUtil.getSingleNode(copletsFragment, "coplets-profile/coplets/coplet[@id='"+copletID+"']", this.xpathProcessor); 408 if (coplet != null) { 409 coplet.getParentNode().removeChild(coplet); 410 } 411 } else if (command.equals("change") && copletID != null) { 412 Node coplet = DOMUtil.getSingleNode(copletsFragment, "coplets-profile/coplets/coplet[@id='"+copletID+"']", this.xpathProcessor); 413 if (coplet != null) { 414 String value; 416 417 value = request.getParameter("portaladmin_title"); 418 if (value != null) DOMUtil.setValueOfNode(DOMUtil.getSingleNode(coplet, "title", this.xpathProcessor), value); 419 420 value = request.getParameter("portaladmin_mand"); 421 if (value != null) DOMUtil.setValueOfNode(DOMUtil.getSingleNode(coplet, "configuration/mandatory", this.xpathProcessor), value); 422 423 value = request.getParameter("portaladmin_sizable"); 424 if (value != null) DOMUtil.setValueOfNode(DOMUtil.getSingleNode(coplet, "configuration/sizable", this.xpathProcessor), value); 425 426 value = request.getParameter("portaladmin_active"); 427 if (value != null) DOMUtil.setValueOfNode(DOMUtil.getSingleNode(coplet, "configuration/active", this.xpathProcessor), value); 428 429 value = request.getParameter("portaladmin_handsize"); 430 if (value != null) DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/handlesSizable", this.xpathProcessor), value); 431 432 value = request.getParameter("portaladmin_handpar"); 433 if (value != null) DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/handlesParameters", this.xpathProcessor), value); 434 435 value = request.getParameter("portaladmin_timeout"); 436 if (value != null) DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/timeout", this.xpathProcessor), value); 437 438 value = request.getParameter("portaladmin_customizable"); 439 if (value != null) DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/customizable", this.xpathProcessor), value); 440 441 value = request.getParameter("portaladmin_persistent"); 442 if (value != null) DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/persistent", this.xpathProcessor), value); 443 444 String resource = request.getParameter("portaladmin_resource"); 445 if (resource != null) { 446 Element resourceNode = (Element )DOMUtil.getSingleNode(coplet, "resource", this.xpathProcessor); 447 resourceNode.getParentNode().removeChild(resourceNode); 448 resourceNode = coplet.getOwnerDocument().createElementNS(null, "resource"); 449 resourceNode.setAttributeNS(null, "uri", resource); 450 coplet.appendChild(resourceNode); 451 } 452 resource = request.getParameter("portaladmin_cust"); 453 boolean isCustom = DOMUtil.getValueAsBooleanOf(coplet, "configuration/customizable", false, this.xpathProcessor); 454 if (resource != null && isCustom ) { 455 Element resourceNode = (Element )DOMUtil.getSingleNode(coplet, "customization", this.xpathProcessor); 456 if (resourceNode != null) resourceNode.getParentNode().removeChild(resourceNode); 457 resourceNode = coplet.getOwnerDocument().createElementNS(null, "customization"); 458 resourceNode.setAttributeNS(null, "uri", resource); 459 coplet.appendChild(resourceNode); 460 } 461 if (!isCustom) { 462 Element resourceNode = (Element )DOMUtil.getSingleNode(coplet, "customization", this.xpathProcessor); 463 if (resourceNode != null) resourceNode.getParentNode().removeChild(resourceNode); 464 } 465 466 value = request.getParameter("portaladmin_newxsl"); 468 if (value != null) { 469 Element tNode = (Element )DOMUtil.selectSingleNode(coplet, "transformation", this.xpathProcessor); 470 Element sNode = tNode.getOwnerDocument().createElementNS(null, "stylesheet"); 471 tNode.appendChild(sNode); 472 sNode.appendChild(sNode.getOwnerDocument().createTextNode(value)); 473 } 474 475 Enumeration keys = request.getParameterNames(); 479 Element sNode; 480 String key; 481 while (keys.hasMoreElements() ) { 482 key = (String )keys.nextElement(); 483 if (key.startsWith("portaladmin_xsl_") ) { 484 value = key.substring(key.lastIndexOf('_')+ 1); 485 sNode = (Element )DOMUtil.getSingleNode(coplet, "transformation/stylesheet[position()="+value+"]", this.xpathProcessor); 486 if (sNode != null) { 487 String xslName = request.getParameter(key); 488 if (xslName.equals("true") ) xslName = "**STYLESHEET**"; 489 DOMUtil.setValueOfNode(sNode, xslName); 490 } 491 } else if (key.startsWith("portaladmin_delxsl_") ) { 492 value = key.substring(key.lastIndexOf('_')+ 1); 493 sNode = (Element )DOMUtil.getSingleNode(coplet, "transformation/stylesheet[position()="+value+"]", this.xpathProcessor); 494 if (sNode != null) { 495 sNode.setAttributeNS(null, "delete", "true"); 496 } 497 } 498 } 499 NodeList delete = DOMUtil.selectNodeList(coplet, "transformation/stylesheet[@delete]", this.xpathProcessor); 500 if (delete != null) { 501 for(int i=0; i < delete.getLength(); i++) { 502 delete.item(i).getParentNode().removeChild(delete.item(i)); 503 } 504 } 505 } 506 } else if (command.equals("new") ) { 507 int index = 0; 509 boolean found = false; 510 Element coplet; 511 Element subNode; 512 513 while (!found) { 514 copletID = "S"+index; 515 coplet = (Element )DOMUtil.getSingleNode(copletsFragment, "coplets-profile/coplets/coplet[@id='"+copletID+"']", this.xpathProcessor); 516 if (coplet == null) { 517 found = true; 518 } else { 519 index++; 520 } 521 } 522 coplet = copletsFragment.getOwnerDocument().createElementNS(null, "coplet"); 523 coplet.setAttributeNS(null, "id", copletID); 524 subNode = coplet.getOwnerDocument().createElementNS(null, "resource"); 525 coplet.appendChild(subNode); 526 subNode.setAttributeNS(null, "uri", "uri_in_sitemap"); 527 528 String title = request.getParameter("portaladmin_title"); 529 if (title == null || title.trim().length() == 0) title = "**NEW COPLET**"; 530 DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/mandatory", this.xpathProcessor), "false"); 531 DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/sizable", this.xpathProcessor), "true"); 532 DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/active", this.xpathProcessor), "false"); 533 DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/handlesParameters", this.xpathProcessor), "true"); 534 DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/handlesSizable", this.xpathProcessor), "false"); 535 DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "title", this.xpathProcessor), title); 536 DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "status/visible", this.xpathProcessor), "true"); 537 DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "status/size", this.xpathProcessor), "max"); 538 DOMUtil.getSingleNode(copletsFragment, "coplets-profile/coplets", this.xpathProcessor).appendChild(coplet); 539 } else if (command.equals("save") ) { 540 541 SourceParameters pars = new SourceParameters(); 542 pars.setSingleParameterValue("profile", "coplet-base"); 543 RequestState state = this.getRequestState(); 544 pars.setSingleParameterValue("application", state.getApplicationName()); 545 pars.setSingleParameterValue("handler", state.getHandlerName()); 546 547 String saveResource = (String )configuration.get(PortalConstants.CONF_COPLETBASE_SAVE_RESOURCE); 548 549 if (saveResource == null) { 550 throw new ProcessingException("portal: No save resource defined for type coplet-base."); 551 } else { 552 553 SourceUtil.writeDOM(saveResource, 554 null, 555 pars, 556 copletsFragment, 557 this.resolver, 558 "xml"); 559 560 this.cleanUpCache(null, null, configuration); 562 } 563 } 564 } finally { 565 this.getTransactionManager().stopWritingTransaction(context); 566 } 567 } 568 569 if (command != null && command.equals("cleancache") ) { 571 this.cleanUpCache(null, null, configuration); 572 } 573 574 String state = request.getParameter(PortalManagerImpl.REQ_PARAMETER_STATE); 575 if (state == null) { 576 state = (String )context.getAttribute(ATTRIBUTE_ADMIN_STATE, PortalConstants.STATE_MAIN); 577 } 578 579 consumer.startElement("", PortalConstants.ELEMENT_ADMINCONF, PortalConstants.ELEMENT_ADMINCONF, XMLUtils.EMPTY_ATTRIBUTES); 581 582 context.setAttribute(ATTRIBUTE_ADMIN_STATE, state); 583 consumer.startElement("", PortalConstants.ELEMENT_STATE, PortalConstants.ELEMENT_STATE, XMLUtils.EMPTY_ATTRIBUTES); 584 consumer.characters(state.toCharArray(), 0, state.length()); 585 consumer.endElement("", PortalConstants.ELEMENT_STATE, PortalConstants.ELEMENT_STATE); 586 587 if (state.equals(PortalConstants.STATE_MAIN) ) { 588 589 Document rolesDF = this.getRoles(); 590 Node roles = null; 591 if (rolesDF != null) roles = DOMUtil.getSingleNode(rolesDF, "roles", this.xpathProcessor); 592 IncludeXMLConsumer.includeNode(roles, consumer, consumer); 593 } 594 595 if (state.equals(PortalConstants.STATE_MAIN_ROLE) ) { 596 597 Document rolesDF = this.getRoles(); 598 Node roles = null; 599 if (rolesDF != null) roles = DOMUtil.getSingleNode(rolesDF, "roles", this.xpathProcessor); 600 IncludeXMLConsumer.includeNode(roles, consumer, consumer); 601 602 |