1 package org.openharmonise.rm.publishing; 19 20 import java.io.OutputStream ; 21 import java.util.Vector ; 22 import java.util.logging.*; 23 24 import org.openharmonise.commons.cache.CacheException; 25 import org.openharmonise.commons.dsi.AbstractDataStoreInterface; 26 import org.openharmonise.commons.xml.*; 27 import org.openharmonise.commons.xml.namespace.NamespaceClashException; 28 import org.openharmonise.rm.*; 29 import org.openharmonise.rm.commands.CommandProcessHandler; 30 import org.openharmonise.rm.config.*; 31 import org.openharmonise.rm.factory.*; 32 import org.openharmonise.rm.logging.*; 33 import org.openharmonise.rm.publishing.renderers.*; 34 import org.openharmonise.rm.resources.AbstractObject; 35 import org.openharmonise.rm.resources.publishing.*; 36 import org.openharmonise.rm.resources.xml.XMLResource; 37 import org.openharmonise.rm.security.authentication.InvalidUserException; 38 import org.openharmonise.rm.security.authorization.*; 39 import org.openharmonise.rm.sessions.*; 40 import org.w3c.dom.*; 41 42 43 52 public class WebPageEngine { 53 54 protected AbstractDataStoreInterface m_dsi = null; 55 56 protected Session m_Session = null; 57 58 protected static XMLPrettyPrint m_xprinter = new XMLPrettyPrint(); 59 60 63 private static final Logger m_logger = Logger.getLogger(WebPageEngine.class.getName()); 64 65 69 public WebPageEngine() { 70 } 71 72 78 public WebPageEngine(AbstractDataStoreInterface con) 79 throws PublishException { 80 m_dsi = con; 81 82 try { 83 m_Session = 84 new Session( 85 m_dsi, 86 Integer.parseInt( 87 ConfigSettings.getProperty( 88 Session.DEFAULT_TIMEOUT_PNAME))); 89 WebPageEngineCache.getInstance(this.m_dsi).addToCache( 90 m_Session.getSessionId(), 91 this); 92 } catch (NumberFormatException e) { 93 throw new PublishException("Number formatting error", e); 94 } catch (SessionException e) { 95 throw new PublishException("Error creating session", e); 96 } catch (ConfigException e) { 97 throw new PublishException("Error getting config data", e); 98 } catch (CacheException e) { 99 throw new PublishException("Error getting object from cache", e); 100 } 101 } 102 103 111 public WebPageEngine(AbstractDataStoreInterface con, String sSessionId) 112 throws PublishException { 113 m_dsi = con; 114 115 if(m_logger.isLoggable(Level.FINE)) { 116 m_logger.logp(Level.FINE, this.getClass().getName(), "WebPageEngine", "Constructing webpage engine for session " + sSessionId); 117 } 118 119 try { 120 m_Session = new Session(m_dsi, sSessionId); 121 } catch (SessionException e) { 122 throw new PublishException("Error creating session", e); 123 } 124 } 125 126 130 public Session getSession() { 131 return m_Session; 132 } 133 134 146 public HarmoniseOutput createXML(WebPage page, State state) 147 throws PublishException { 148 XMLDocument xml = null; 149 HarmoniseOutput xout = null; 150 151 if(m_logger.isLoggable(Level.FINE)) { 152 m_logger.logp(Level.FINE, this.getClass().getName(), "createXML", "Generating XML for webpage " + page.getId()); 153 } 154 155 try { 156 m_Session.processState(state, page.getTimeout()); 157 158 if (AuthorizationValidator.isVisible(m_Session.getUser(), page) 159 == false) { 160 if(m_logger.isLoggable(Level.INFO)) { 161 m_logger.logp(Level.INFO, this.getClass().getName(), "createXML", "User id " + m_Session.getUser().getId() + " not allowed to view page " + page.getId()); 162 } 163 throw new InvalidUserException("User does not have permission to view page"); 164 } 165 xml = page.getXML().getXIncludeResolvedDocument(); 166 167 } catch (SessionException e) { 168 throw new PublishException("Error processing state", e); 169 } catch (DataAccessException e) { 170 throw new PublishException("Data access error", e); 171 } catch (AuthorizationException e) { 172 throw new PublishException("Error validating user", e); 173 } catch (InvalidUserException e) { 174 throw new PublishException("Invalid User", e); 175 } 176 try { 177 xout = processXML(xml.getDocumentElement(), state); 178 } catch (PublishException e) { 179 m_logger.log(Level.SEVERE, "Template XML form for page id" 180 + page.getId() 181 + " was invalid," 182 + " unable to build any XML", e); 183 throw new RuntimeException ( 184 "Template XML form for page id" 185 + page.getId() 186 + " was invalid," 187 + " unable to build any XML"); 188 } 189 return xout; 190 } 191 192 204 public HarmoniseOutput createXML(Element topEl, State state) 205 throws PublishException { 206 XMLDocument xdoc = null; 207 try { 208 XMLResource xml = new XMLResource(); 209 m_xprinter.setNamespaceAware(true); 210 xml.setContent(m_xprinter.printNode(topEl)); 211 xdoc = xml.getXIncludeResolvedDocument(); 212 } catch (PopulateException e) { 213 throw new PublishException("Error populating xml resource", e); 214 } catch (NamespaceClashException e) { 215 throw new PublishException("Namespace error", e); 216 } catch (DataAccessException e) { 217 throw new PublishException("Data access error", e); 218 } 219 220 return processXML(xdoc.getDocumentElement(), state); 221 } 222 223 234 private HarmoniseOutput processXML(Element topEl, State state) 235 throws PublishException { 236 Element pageState; 237 HarmoniseOutput xOutput = new HarmoniseOutput(m_dsi); 238 239 Element tempPublishEl; 240 Element root; 241 root = xOutput.createElement(WebPage.TAG_HARMONISE); 242 xOutput.appendChild(root); 243 244 tempPublishEl = null; 245 246 pageState = xOutput.createElement(State.TAG_STATE); 247 root.appendChild(pageState); 248 249 pageState.appendChild(m_Session.publish(xOutput)); 250 251 copyStateChildren((Node) pageState, state, xOutput); 252 253 NodeList children = topEl.getChildNodes(); 254 255 for (int i = 0; i < children.getLength(); i++) { 256 if (children.item(i).getNodeType() != Node.ELEMENT_NODE) { 257 continue; 258 } 259 260 Element next = (Element) children.item(i); 261 String sTagName = next.getTagName(); 262 263 Vector ignore_tags = new Vector (); 264 265 ignore_tags.add(WebPage.TAG_PAGETITLE); 266 267 try { 268 if (sTagName.equals(WebPage.TAG_NAVIGATION)) { 269 tempPublishEl = navigation(next, state, xOutput); 270 } else if (sTagName.equals(Template.TAG_TEMPLATE)) { 271 tempPublishEl = publishTemplate(next, state, xOutput); 272 } else if ( 273 sTagName.equals(CommandProcessHandler.TAG_WORKFLOW)) { 274 CommandProcessHandler cmdHandler = 275 new CommandProcessHandler(m_dsi); 276 277 tempPublishEl = cmdHandler.publish(next, xOutput, state); 278 } else if (ignore_tags.contains(sTagName)) { 279 tempPublishEl = (Element) xOutput.copyNode(next); 280 } else { 281 try { 282 Publishable pubObj = 283 HarmoniseObjectFactory.instantiatePublishableObject( 284 this.m_dsi, 285 next, 286 state); 287 288 tempPublishEl = pubObj.publish(next, xOutput, state); 289 } catch (HarmoniseFactoryException e) { 290 tempPublishEl = (Element) xOutput.copyNode(next); 291 root.appendChild(e.publish(xOutput)); 292 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 293 } 294 } 295 } catch (PublishException e) { 296 tempPublishEl = e.publish(xOutput); 297 } 298 299 if (tempPublishEl != null) { 300 root.appendChild(tempPublishEl); 301 } 302 303 } 304 305 if (((Node) root).getChildNodes().getLength() == 0) { 306 throw new PublishException("Unable to publish Harmonise Page."); 307 } 308 309 return xOutput; 310 } 311 312 315 public String toString() { 316 StringBuffer strbuf = new StringBuffer (); 317 318 319 strbuf.append("WepPageEngine Session details:").append( 320 m_Session.toString()); 321 322 323 return strbuf.toString(); 324 } 325 326 335 public void render(WebPage page, State state, OutputStream out) 336 throws PublishException, RenderException { 337 338 if(m_logger.isLoggable(Level.FINE)) { 339 m_logger.logp(Level.FINE, this.getClass().getName(), "render", "Rendering page " + page.getId()); 340 } 341 342 XMLDocument xdoc = createXML(page, state); 343 344 try { 345 PageRenderer renderer = 346 PageRendererFactory.getRenderer(page.getXSL().getOutputType()); 347 348 renderer.render(xdoc, page.getXSL().getTemplates(), out); 349 logPublish(page, state); 350 } catch (DataAccessException e) { 351 throw new PublishException("Error occured accessing page data", e); 352 } 353 } 354 355 365 public void render( 366 WebPage page, 367 State state, 368 PageRenderer renderer, 369 OutputStream out) 370 throws PublishException, RenderException { 371 XMLDocument xdoc = createXML(page, state); 372 373 try { 374 renderer.render(xdoc, page.getXSL().getTemplates(), out); 375 376 logPublish(page, state); 377 378 } catch (DataAccessException e) { 379 throw new PublishException("Error occured accessing page data", e); 380 } 381 } 382 383 386 387 394 protected void logPublish(WebPage page, State state) 395 throws PublishException { 396 397 try { 398 PublishLogEvent event = new PublishLogEvent(); 399 400 event.setEventObject(page); 401 event.setState(state); 402 403 EventLogController.getInstance().logEvent(event); 404 } catch (PopulateException e) { 405 throw new PublishException("Error setting state of event", e); 406 } catch (LogException e) { 407 throw new PublishException("Error logging event", e); 408 } 409 410 } 411 412 422 protected Element navigation(Element nav, State state, HarmoniseOutput output) 423 throws PublishException { 424 Element tempEl = null; 425 426 Element newNav = output.createElement(WebPage.TAG_NAVIGATION); 427 428 Element childNav = null; 429 430 NamedNodeMap navAttributes = nav.getAttributes(); 431 Node navName = navAttributes.getNamedItem("name"); 432 433 newNav.setAttribute("name", navName.getNodeValue()); 434 435 Node navDescription = navAttributes.getNamedItem("description"); 436 437 if (navDescription != null) { 438 newNav.setAttribute("description", navDescription.getNodeValue()); 439 } 440 441 NodeList children = nav.getChildNodes(); 442 443 for (int i = 0; i < children.getLength(); i++) { 444 if (children.item(i).getNodeType() != Node.ELEMENT_NODE) { 445 continue; 446 } 447 448 Element next = (Element) children.item(i); 449 450 if (next.getTagName().equals(Template.TAG_TEMPLATE)) { 451 452 tempEl = publishTemplate(next, state, output); 453 454 if (tempEl != null) { 455 newNav.appendChild(tempEl); 456 } 457 458 } else if (next.getTagName().equals(WebPage.TAG_NAVIGATION)) { 459 childNav = null; 460 childNav = navigation(next, state, output); 461 462 if (childNav != null) { 463 newNav.appendChild(childNav); 464 } 465 } else if (next.getTagName().equals(WebPage.TAG_ANCILLARY_TEXT)) { 466 newNav.appendChild(output.copyNode(next)); 467 } else if (next.getTagName().equals(AbstractObject.TAG_LINK)) { 468 newNav.appendChild(output.copyNode(next)); 469 } else { 470 471 try { 472 Publishable pubObj = 473 HarmoniseObjectFactory.instantiatePublishableObject( 474 this.m_dsi, 475 next, 476 state); 477 478 newNav.appendChild(pubObj.publish(next, output, state)); 479 } catch (HarmoniseFactoryException e) { 480 throw new PublishException( 481 "Error instantiating object from factory", 482 e); 483 } catch (PublishException e) { 484 newNav.appendChild(e.publish(output)); 485 } 486 487 } 488 } 489 490 return newNav; 491 } 492 493 503 protected Element publishTemplate( 504 Element templateEl, 505 State state, 506 HarmoniseOutput output) 507 throws PublishException { 508 if (templateEl.getTagName().equalsIgnoreCase(Template.TAG_TEMPLATE) 509 == false) { 510 throw new InvalidXMLElementException("Template tag needed"); 511 } 512 513 Element returnEl = null; 514 Template templ = null; 515 try { 516 templ = (Template) HarmoniseObjectFactory.instantiateHarmoniseObject(m_dsi, Template.class.getName(), Integer.parseInt( 517 templateEl.getAttribute(AbstractObject.ATTRIB_ID))); 518 } catch (NumberFormatException e) { 519 throw new PublishException(e); 520 } catch (HarmoniseFactoryException e) { 521 throw new PublishException(e); 522 } 523 Element templRoot = null; 524 try { 525 templRoot = templ.getTemplateRootElement(); 526 } catch (DataAccessException e) { 527 throw new PublishException( 528 "Error occured getting template root", 529 e); 530 } 531 NodeList templChildren = templateEl.getChildNodes(); 532 533 int nPageId = -2; 534 NodeList pageNodes = templateEl.getElementsByTagName(WebPage.TAG_PAGE); 535 536 if (pageNodes.getLength() > 0) { 537 nPageId = 538 Integer.parseInt( 539 ((Element) pageNodes.item(0)).getAttribute( 540 AbstractObject.ATTRIB_ID)); 541 } 542 543 for (int i = 0; i < templChildren.getLength(); i++) { 544 if (templChildren.item(i).getNodeType() == Node.ELEMENT_NODE) { 545 Element child = (Element) templChildren.item(i); 546 547 if (templRoot 548 .getTagName() 549 .equalsIgnoreCase(child.getTagName())) { 550 551 Publishable pubObj = null; 552 try { 553 pubObj = 554 HarmoniseObjectFactory.instantiatePublishableObject( 555 this.m_dsi, 556 child, 557 state); 558 } catch (HarmoniseFactoryException e) { 559 throw new PublishException( 560 "Error occured getting object from factory", 561 e); 562 } 563 564 if (pubObj != null) { 565 returnEl = 566 templ.publishObjectToElement(pubObj, output, state); 567 568 String sStateId = 569 child.getAttribute(State.ATTRIB_STATE_ID); 570 571 if ((sStateId != null) && (sStateId.length() > 0)) { 572 returnEl.setAttribute( 573 State.ATTRIB_STATE_ID, 574 sStateId); 575 } 576 577 output.addPageIdToLinkNode( 578 state.getLoggedInUser(), 579 returnEl, 580 nPageId); 581 } 582 583 } 584 } 585 } 586 587 return returnEl; 588 } 589 590 598 protected void copyStateChildren( 599 Node appendTo, 600 State state, 601 HarmoniseOutput output) { 602 Node stateRoot = state.getDocumentElement(); 603 NodeList stateElements = stateRoot.getChildNodes(); 604 605 for (int i = 0; i < stateElements.getLength(); i++) { 606 607 if ((stateElements.item(i).getNodeType() == Node.ELEMENT_NODE) 608 && (((Element) stateElements.item(i)) 609 .getTagName() 610 .equals(Session.TAG_SESSION))) { 611 continue; 612 } 613 614 appendTo.appendChild(output.copyNode(stateElements.item(i))); 615 } 616 } 617 618 624 public void assignSessionId(State state) { 625 String sSessionId = m_Session.getSessionId(); 626 627 state.setSessionId(sSessionId); 628 } 629 630 } | Popular Tags |