1 19 package org.openharmonise.rm.resources.xml; 20 21 22 import java.io.*; 23 import java.util.StringTokenizer ; 24 import java.util.logging.*; 25 26 import javax.xml.parsers.*; 27 import javax.xml.transform.*; 28 import javax.xml.transform.stream.StreamSource ; 29 30 import oreilly.hcj.references.WeakHashSet; 31 32 import org.openharmonise.commons.cache.*; 33 import org.openharmonise.commons.dsi.*; 34 import org.openharmonise.commons.dsi.dml.UpdateStatement; 35 import org.openharmonise.commons.net.MimeTypeMapping; 36 import org.openharmonise.commons.net.MimeTypeMapping.Mapping; 37 import org.openharmonise.commons.xml.namespace.NamespaceType; 38 import org.openharmonise.rm.*; 39 import org.openharmonise.rm.config.*; 40 import org.openharmonise.rm.factory.*; 41 import org.openharmonise.rm.metadata.*; 42 import org.openharmonise.rm.resources.AbstractParentObject; 43 import org.openharmonise.rm.resources.content.*; 44 import org.openharmonise.rm.resources.lifecycle.*; 45 import org.openharmonise.rm.resources.metadata.properties.Property; 46 import org.w3c.dom.*; 47 import org.xml.sax.SAXException ; 48 49 50 51 58 public class XSLResource extends Asset implements CacheDependant, DependableCacheObject { 59 60 private static final String XSL_ROOT_PNAME = "XSL_PATH"; 62 63 public static String TBL_XSL = "xsl"; 65 66 public static final String PROP_OUTPUT_TYPE = "OUTPUT"; 68 69 public static final String TAG_INCLUDE = "include"; 70 public static final String TAG_IMPORT = "import"; 71 public static final String ATTRIB_HREF = "href"; 72 73 private static final String ROOT_PATH = "/root"; 74 75 private WeakHashSet m_dependants = null; 76 77 79 private static final String DEFAULT_OUTPUT_TYPE = MimeTypeMapping.TEXT.getMimeType();; 80 81 private Templates m_templates = null; 82 83 private static Logger m_logger = Logger.getLogger(XSLResource.class.getName()); 84 85 { 87 m_sContentType = MimeTypeMapping.XSLT.getMimeType(); 88 } 89 90 93 public XSLResource() { 94 super(); 95 } 96 97 102 public XSLResource(AbstractDataStoreInterface dbintrf) { 103 super(dbintrf); 104 } 105 106 112 public XSLResource(AbstractDataStoreInterface dbintrf, int nId) { 113 super(dbintrf, nId); 114 } 115 116 119 public String getDBTableName() { 120 return TBL_XSL; 121 } 122 123 126 public String getParentObjectClassName() { 127 return XSLResourceGroup.class.getName(); 128 } 129 130 137 public Templates getTemplates() throws DataAccessException { 138 139 if (m_templates == null) { 140 141 TransformerFactory factory = TransformerFactory.newInstance(); 142 try { 143 File file = getContentFile(); 144 145 StreamSource ssource = new StreamSource (new FileReader(file)); 146 ssource.setSystemId(file); 147 148 m_templates = factory.newTemplates(ssource); 149 150 try { 151 DocumentBuilderFactory docfactory = DocumentBuilderFactory.newInstance(); 152 153 docfactory.setNamespaceAware(true); 154 155 DocumentBuilder builder = docfactory.newDocumentBuilder(); 156 157 org.w3c.dom.Document doc = builder.parse(file); 158 159 NodeList nodes = doc.getDocumentElement().getElementsByTagNameNS(NamespaceType.XSLT.getURI(), TAG_INCLUDE); 160 161 handleXSLReferences(nodes); 162 163 nodes = doc.getDocumentElement().getElementsByTagNameNS(NamespaceType.XSLT.getURI(), TAG_IMPORT); 164 165 handleXSLReferences(nodes); 166 167 } catch (ConfigException e) { 171 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 172 } catch (DataAccessException e) { 173 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 174 } catch (FactoryConfigurationError e) { 175 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 176 } catch (ParserConfigurationException e) { 177 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 178 } catch (SAXException e) { 179 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 180 } catch (IOException e) { 181 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 182 } catch (HarmoniseFactoryException e) { 183 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 184 } 185 186 } catch (TransformerConfigurationException e) { 187 throw new DataAccessException( 188 "Error occured creating templates",e); 189 } catch (FileNotFoundException e) { 190 throw new DataAccessException( 191 "Error occured creating templates",e); 192 } 193 } 194 195 return m_templates; 196 } 197 198 207 private void handleXSLReferences(NodeList nodes) 208 throws ConfigException, DataAccessException, HarmoniseFactoryException { 209 for (int i = 0; i < nodes.getLength(); i++) { 210 Node node = (Node) nodes.item(i); 211 212 if(node.getNodeType() == Node.ELEMENT_NODE) { 213 Element el = (Element) node; 214 215 String sHREF = el.getAttribute(ATTRIB_HREF); 216 217 if(sHREF != null && sHREF.length() > 0) { 218 String sOHpath = getOHPath(sHREF); 219 220 XSLResource xsl = (XSLResource) HarmoniseObjectFactory.instantiateHarmoniseObject(m_dsi, XSLResource.class.getName(), sOHpath); 221 if(xsl != null) { 222 xsl.addEditEventListener(this); 223 xsl.addDependant(this); 224 } 225 226 } 227 } 228 } 229 } 230 231 234 public void setIsChanged(boolean bIsChanged) { 235 if(bIsChanged == true) { 237 m_templates = null; 238 } 239 240 super.setIsChanged(bIsChanged); 241 } 242 243 251 public String getOutputType() throws DataAccessException { 252 String sOutput = DEFAULT_OUTPUT_TYPE; 253 254 Profile prof = getProfile(); 255 256 try { 257 GeneralPropertyInstance propInst = (GeneralPropertyInstance) prof.getPropertyInstance(PROP_OUTPUT_TYPE); 258 259 if(propInst != null) { 260 sOutput = (String ) propInst.getValue(); 261 } else { 262 sOutput = MimeTypeMapping.HTML.getMimeType(); 263 } 264 } catch (InvalidPropertyInstanceException e) { 265 throw new DataAccessException(e.getLocalizedMessage(),e); 266 } 267 268 return sOutput; 269 } 270 271 279 public void setOutputType(String sOutput) throws PopulateException { 280 try { 281 Profile prof = getProfile(); 282 283 Property outProp = (Property) HarmoniseObjectFactory.instantiateHarmoniseObject(m_dsi,Property.class.getName(),PROP_OUTPUT_TYPE); 284 285 GeneralPropertyInstance propInst = (GeneralPropertyInstance) prof.getPropertyInstance(PROP_OUTPUT_TYPE); 286 287 if(propInst != null) { 288 propInst.clearValues(); 289 } else { 290 propInst = new GeneralPropertyInstance(m_dsi,outProp,prof); 291 } 292 293 propInst.addValue(sOutput); 294 } catch (DataAccessException e) { 295 throw new PopulateException("Error occured getting profile",e); 296 } catch (HarmoniseFactoryException e) { 297 throw new PopulateException("Error occured getting property from factory",e); 298 } catch (InvalidPropertyValueException e) { 299 throw new PopulateException("Invalid value",e); 300 } catch (InvalidPropertyInstanceException e) { 301 throw new PopulateException("Invalid property",e); 302 } 303 304 } 305 306 307 308 311 protected File createFile() 312 throws AssetException, ConfigException, DataAccessException { 313 String sFilePath = null; 314 315 sFilePath = 316 ConfigSettings.getProperty(XSL_ROOT_PNAME).replace( 317 '/', 318 File.separatorChar); 319 320 String sName = getName(); 321 322 String sContentType = getContentType(); 323 Mapping xsltType = MimeTypeMapping.XSLT; 324 if(xsltType.getMimeTypes().contains(sContentType) == false) { 325 throw new AssetException("Wrong mime type for this object - " + sContentType); 326 } 327 328 String sSuffix = xsltType.getExtension(); 329 330 StringBuffer sFullPath = new StringBuffer (); 331 sFullPath.append(sFilePath); 332 333 if(exists() == true) { 335 AbstractParentObject parent = getRealParent(); 336 337 if(parent != null) { 338 339 String sParentPath = parent.getFullPath().replace('/', File.separatorChar); 340 341 String sRootlessPath = sParentPath.substring(ROOT_PATH.length()); 342 343 if(sRootlessPath.length() > 0) { 345 sFullPath.append(sRootlessPath); 346 } 347 } 348 349 } 350 351 sFullPath.append(File.separatorChar); 352 353 sFullPath.append(sName); 354 355 if(exists() == false || isLiveVersion() == false) { 356 sFullPath.append("_").append(getKey()); 357 } 358 359 sFullPath.append(".").append(sSuffix); 360 361 File test = new File(sFullPath.toString()); 363 364 if (ensureParentExists(test) == false) { 365 throw new AssetException("Trouble creating asset file"); 366 } 367 368 return test; 369 } 370 371 374 public Editable changeStatus(Status status) throws EditException { 375 Editable result = super.changeStatus(status); 376 377 try { 378 File oldFile = getContentFile(); 380 File newFile = createFile(); 381 382 if(oldFile.equals(newFile) == false) { 383 if(moveFile(oldFile, newFile) == false) { 384 throw new EditException("File manipulation failed"); 385 } 386 m_sURI = newFile.getAbsolutePath(); 387 388 m_sURI = getRelativePath(m_sURI); 389 390 UpdateStatement update = new UpdateStatement(); 391 392 update.addColumnValue(getInstanceColumnRef(Asset.CLMN_URI, isHistorical()),m_sURI); 393 394 update.addWhereCondition(getInstanceColumnRef(ATTRIB_KEY, isHistorical()), "=", getKey()); 395 396 m_dsi.execute(update); 397 } 398 399 } catch (DataAccessException e) { 400 throw new EditException(e.getLocalizedMessage(),e); 401 } catch (AssetException e) { 402 throw new EditException(e.getLocalizedMessage(),e); 403 } catch (ConfigException e) { 404 throw new EditException(e.getLocalizedMessage(),e); 405 } catch (DataStoreException e) { 406 throw new EditException(e.getLocalizedMessage(),e); 407 } 408 409 return result; 410 } 411 412 415 protected boolean isAssetSavedAsText(String sContentType) { 416 return false; 417 } 418 419 422 public void setContentType(String sContentType) throws PopulateException { 423 424 if(MimeTypeMapping.XSLT.getMimeTypes().contains(sContentType) == false) { 425 throw new PopulateException("Invalid content type"); 426 } 427 428 super.setContentType(sContentType); 429 } 430 431 434 public Editable archive() throws EditException { 435 XSLResource result = (XSLResource) super.archive(); 436 437 try { 438 if(result != null) { 440 441 File oldFile = getContentFile(); 443 File newFile = result.createFile(); 444 445 if(oldFile.equals(newFile) == false) { 446 if(copyFile(oldFile, newFile) == false) { 447 throw new EditException("File manipulation failed"); 448 } 449 m_sURI = newFile.getAbsolutePath(); 450 451 m_sURI = getRelativePath(m_sURI); 452 453 UpdateStatement update = new UpdateStatement(); 454 455 update.addColumnValue(result.getInstanceColumnRef(Asset.CLMN_URI, result.isHistorical()),m_sURI); 456 457 update.addWhereCondition(result.getInstanceColumnRef(ATTRIB_KEY, result.isHistorical()), "=", result.getKey()); 458 459 m_dsi.execute(update); 460 } 461 } 462 463 stopListening(); 466 467 } catch (DataAccessException e) { 468 throw new EditException(e.getLocalizedMessage(),e); 469 } catch (AssetException e) { 470 throw new EditException(e.getLocalizedMessage(),e); 471 } catch (ConfigException e) { 472 throw new EditException(e.getLocalizedMessage(),e); 473 } catch (DataStoreException e) { 474 throw new EditException(e.getLocalizedMessage(),e); 475 } 476 477 return result; 478 } 479 480 486 private void stopListening() throws DataAccessException { 487 TransformerFactory factory = TransformerFactory.newInstance(); 488 try { 489 File file = getContentFile(); 490 491 StreamSource ssource = new StreamSource (new FileReader(file)); 492 ssource.setSystemId(file); 493 494 m_templates = factory.newTemplates(ssource); 495 496 try { 497 DocumentBuilderFactory docfactory = DocumentBuilderFactory.newInstance(); 498 499 docfactory.setNamespaceAware(true); 500 501 DocumentBuilder builder = docfactory.newDocumentBuilder(); 502 503 org.w3c.dom.Document doc = builder.parse(file); 504 505 NodeList nodes = doc.getDocumentElement().getElementsByTagNameNS(NamespaceType.XSLT.getURI(), TAG_INCLUDE); 506 507 stopListeningToXSLResources(nodes); 508 509 nodes = doc.getDocumentElement().getElementsByTagNameNS(NamespaceType.XSLT.getURI(), TAG_IMPORT); 510 511 stopListeningToXSLResources(nodes); 512 513 } catch (ConfigException e) { 517 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 518 } catch (DataAccessException e) { 519 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 520 } catch (FactoryConfigurationError e) { 521 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 522 } catch (ParserConfigurationException e) { 523 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 524 } catch (SAXException e) { 525 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 526 } catch (IOException e) { 527 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 528 } catch (HarmoniseFactoryException e) { 529 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 530 } 531 532 } catch (TransformerConfigurationException e) { 533 throw new DataAccessException( 534 "Error occured creating templates",e); 535 } catch (FileNotFoundException e) { 536 throw new DataAccessException( 537 "Error occured creating templates",e); 538 } 539 540 } 541 542 551 private void stopListeningToXSLResources(NodeList nodes) throws ConfigException, DataAccessException, HarmoniseFactoryException { 552 for (int i = 0; i < nodes.getLength(); i++) { 553 Node node = (Node) nodes.item(i); 554 555 if(node.getNodeType() == Node.ELEMENT_NODE) { 556 Element el = (Element) node; 557 558 String sHREF = el.getAttribute(ATTRIB_HREF); 559 560 if(sHREF != null && sHREF.length() > 0) { 561 String sOHpath = getOHPath(sHREF); 562 563 XSLResource xsl = (XSLResource) HarmoniseObjectFactory.instantiateHarmoniseObject(m_dsi, XSLResource.class.getName(), sOHpath); 564 if(xsl != null) { 565 xsl.removeEditEventListener(this); 566 xsl.removeDependant(this); 567 } 568 569 } 570 } 571 } 572 573 } 574 575 private String getOHPath(File file) throws ConfigException, DataAccessException { 576 String sFilePath = file.getAbsolutePath(); 577 578 return getOHPath(sFilePath); 579 } 580 581 private String getOHPath(String sFilePath) throws ConfigException, DataAccessException { 582 583 StringBuffer sBuf = new StringBuffer (); 584 585 int nLastDotIndex = sFilePath.lastIndexOf("."); 586 587 sFilePath = sFilePath.substring(0, nLastDotIndex); 588 589 if(isAbsolutePath(sFilePath)) { 590 String sXSLRootFilePath = ConfigSettings.getProperty(XSL_ROOT_PNAME); 591 592 String sTempPath = sFilePath.substring(sXSLRootFilePath.length()); 593 594 sBuf.append(ROOT_PATH).append(sTempPath.replace(File.separatorChar, '/')); 595 } else { 596 if(sFilePath.startsWith(".." + File.separator) 597 || sFilePath.startsWith("." + File.separator)) { 598 599 sBuf.append(resolveDots(sFilePath)).append(sFilePath.replace(File.separatorChar, '/')); 600 } else if(sFilePath.startsWith(File.separator)) { 601 } else { 604 sBuf.append(getPath()).append("/").append(sFilePath.replace(File.separatorChar, '/')); 605 } 606 } 607 608 return sBuf.toString(); 609 } 610 611 615 private String resolveDots(String sFilePath) throws DataAccessException { 616 617 StringTokenizer tokenizer = new StringTokenizer (sFilePath); 618 619 AbstractParentObject parent = this.getRealParent(); 620 621 while(tokenizer.hasMoreTokens()) { 622 String token = tokenizer.nextToken(); 623 624 if(token.equals("..")) { 625 parent = parent.getRealParent(); 626 } 627 } 628 629 return parent.getFullPath(); 630 } 631 632 private String removeDots(String sFilePath) { 633 StringTokenizer tokenizer = new StringTokenizer (sFilePath,File.separator); 634 635 StringBuffer sbuf = new StringBuffer (); 636 637 while(tokenizer.hasMoreTokens()) { 638 String token = tokenizer.nextToken(); 639 640 if(token.startsWith(".") == false) { 641 sbuf.append("/").append(token); 642 } 643 } 644 645 return sbuf.toString(); 646 } 647 648 652 private boolean isAbsolutePath(String sFilePath) { 653 boolean bIsAbsolutePath = false; 654 File[] roots = File.listRoots(); 655 656 for (int i = 0; i < roots.length; i++) { 657 if(sFilePath.startsWith(roots[i].getAbsolutePath())) { 658 bIsAbsolutePath = true; 659 break; 660 } 661 } 662 663 return bIsAbsolutePath; 664 } 665 666 669 public void workflowObjectArchived(EditEvent event) { 670 Object src = event.getSource(); 671 672 if(event.getSource() instanceof XSLResource) { 673 m_templates = null; 674 675 XSLResource xsl = (XSLResource) src; 676 677 xsl.removeEditEventListener(this); 678 } 679 680 super.workflowObjectArchived(event); 681 } 682 683 686 public boolean hasDependants() { 687 return (m_dependants != null && m_dependants.size() > 0); 688 } 689 690 693 public void addDependant(CacheDependant dep) { 694 if(m_dependants == null) { 695 m_dependants = new WeakHashSet(); 696 } 697 698 if(m_dependants.contains(dep) == false) { 699 m_dependants.add(dep); 700 } 701 } 702 703 706 public void removeDependant(CacheDependant dep) { 707 if(m_dependants != null) { 708 m_dependants.remove(dep); 709 } 710 711 } 712 713 716 public void setIsContentChanged(boolean bContentChanged) { 717 if(bContentChanged == true) { 718 m_templates = null; 719 } 720 super.setIsContentChanged(bContentChanged); 721 } 722 723 726 public String getAssetRoot() throws DataAccessException { 727 String sRoot = null; 728 729 try { 730 sRoot = ConfigSettings.getProperty(XSL_ROOT_PNAME); 731 } catch (ConfigException e) { 732 throw new DataAccessException(e); 733 } 734 735 return sRoot; 736 } 737 740 public void setContentFile(File assetFile) throws PopulateException { 741 m_templates = null; 742 super.setContentFile(assetFile); 743 } 744 } 745 | Popular Tags |