001: /*
002: * The contents of this file are subject to the
003: * Mozilla Public License Version 1.1 (the "License");
004: * you may not use this file except in compliance with the License.
005: * You may obtain a copy of the License at http://www.mozilla.org/MPL/
006: *
007: * Software distributed under the License is distributed on an "AS IS"
008: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
009: * See the License for the specific language governing rights and
010: * limitations under the License.
011: *
012: * The Initial Developer of the Original Code is Simulacra Media Ltd.
013: * Portions created by Simulacra Media Ltd are Copyright (C) Simulacra Media Ltd, 2004.
014: *
015: * All Rights Reserved.
016: *
017: * Contributor(s):
018: */
019: package org.openharmonise.rm.resources.xml;
020:
021: import java.io.*;
022: import java.util.StringTokenizer;
023: import java.util.logging.*;
024:
025: import javax.xml.parsers.*;
026: import javax.xml.transform.*;
027: import javax.xml.transform.stream.StreamSource;
028:
029: import oreilly.hcj.references.WeakHashSet;
030:
031: import org.openharmonise.commons.cache.*;
032: import org.openharmonise.commons.dsi.*;
033: import org.openharmonise.commons.dsi.dml.UpdateStatement;
034: import org.openharmonise.commons.net.MimeTypeMapping;
035: import org.openharmonise.commons.net.MimeTypeMapping.Mapping;
036: import org.openharmonise.commons.xml.namespace.NamespaceType;
037: import org.openharmonise.rm.*;
038: import org.openharmonise.rm.config.*;
039: import org.openharmonise.rm.factory.*;
040: import org.openharmonise.rm.metadata.*;
041: import org.openharmonise.rm.resources.AbstractParentObject;
042: import org.openharmonise.rm.resources.content.*;
043: import org.openharmonise.rm.resources.lifecycle.*;
044: import org.openharmonise.rm.resources.metadata.properties.Property;
045: import org.w3c.dom.*;
046: import org.xml.sax.SAXException;
047:
048: /**
049: * This object represents a XSLT resource in Harmonise.
050: *
051: * @author mike
052: * @version $Revision: 1.6 $
053: *
054: */
055: public class XSLResource extends Asset implements CacheDependant,
056: DependableCacheObject {
057:
058: //Config parameter
059: private static final String XSL_ROOT_PNAME = "XSL_PATH";
060:
061: //DB constants
062: public static String TBL_XSL = "xsl";
063:
064: //System property
065: public static final String PROP_OUTPUT_TYPE = "OUTPUT";
066:
067: public static final String TAG_INCLUDE = "include";
068: public static final String TAG_IMPORT = "import";
069: public static final String ATTRIB_HREF = "href";
070:
071: private static final String ROOT_PATH = "/root";
072:
073: private WeakHashSet m_dependants = null;
074:
075: //defaults
076:
077: private static final String DEFAULT_OUTPUT_TYPE = MimeTypeMapping.TEXT
078: .getMimeType();;
079:
080: private Templates m_templates = null;
081:
082: private static Logger m_logger = Logger.getLogger(XSLResource.class
083: .getName());
084:
085: //initialise content type
086: {
087: m_sContentType = MimeTypeMapping.XSLT.getMimeType();
088: }
089:
090: /**
091: * Basic constructor
092: */
093: public XSLResource() {
094: super ();
095: }
096:
097: /**
098: * Basic constructor with an interface to the DB.
099: *
100: * @param dbintrf
101: */
102: public XSLResource(AbstractDataStoreInterface dbintrf) {
103: super (dbintrf);
104: }
105:
106: /**
107: * Standard constructor for a known existing xslt resource.
108: *
109: * @param dbintrf
110: * @param nId
111: */
112: public XSLResource(AbstractDataStoreInterface dbintrf, int nId) {
113: super (dbintrf, nId);
114: }
115:
116: /* (non-Javadoc)
117: * @see org.openharmonise.rm.dsi.DataStoreObject#getDBTableName()
118: */
119: public String getDBTableName() {
120: return TBL_XSL;
121: }
122:
123: /* (non-Javadoc)
124: * @see org.openharmonise.rm.resources.AbstractChildObject#getParentObjectClassName()
125: */
126: public String getParentObjectClassName() {
127: return XSLResourceGroup.class.getName();
128: }
129:
130: /**
131: * Returns a <code>Templates</code> object created from the XML document represented
132: * by this object.
133: *
134: * @return
135: * @throws DataAccessException
136: */
137: public Templates getTemplates() throws DataAccessException {
138:
139: if (m_templates == null) {
140:
141: TransformerFactory factory = TransformerFactory
142: .newInstance();
143: try {
144: File file = getContentFile();
145:
146: StreamSource ssource = new StreamSource(new FileReader(
147: file));
148: ssource.setSystemId(file);
149:
150: m_templates = factory.newTemplates(ssource);
151:
152: try {
153: DocumentBuilderFactory docfactory = DocumentBuilderFactory
154: .newInstance();
155:
156: docfactory.setNamespaceAware(true);
157:
158: DocumentBuilder builder = docfactory
159: .newDocumentBuilder();
160:
161: org.w3c.dom.Document doc = builder.parse(file);
162:
163: NodeList nodes = doc.getDocumentElement()
164: .getElementsByTagNameNS(
165: NamespaceType.XSLT.getURI(),
166: TAG_INCLUDE);
167:
168: handleXSLReferences(nodes);
169:
170: nodes = doc.getDocumentElement()
171: .getElementsByTagNameNS(
172: NamespaceType.XSLT.getURI(),
173: TAG_IMPORT);
174:
175: handleXSLReferences(nodes);
176:
177: //only log errors associated to includes and let
178: //any errors come through when directly accessing
179: //the include XSLTs themselves
180: } catch (ConfigException e) {
181: m_logger.log(Level.WARNING,
182: e.getLocalizedMessage(), e);
183: } catch (DataAccessException e) {
184: m_logger.log(Level.WARNING,
185: e.getLocalizedMessage(), e);
186: } catch (FactoryConfigurationError e) {
187: m_logger.log(Level.WARNING,
188: e.getLocalizedMessage(), e);
189: } catch (ParserConfigurationException e) {
190: m_logger.log(Level.WARNING,
191: e.getLocalizedMessage(), e);
192: } catch (SAXException e) {
193: m_logger.log(Level.WARNING,
194: e.getLocalizedMessage(), e);
195: } catch (IOException e) {
196: m_logger.log(Level.WARNING,
197: e.getLocalizedMessage(), e);
198: } catch (HarmoniseFactoryException e) {
199: m_logger.log(Level.WARNING,
200: e.getLocalizedMessage(), e);
201: }
202:
203: } catch (TransformerConfigurationException e) {
204: throw new DataAccessException(
205: "Error occured creating templates", e);
206: } catch (FileNotFoundException e) {
207: throw new DataAccessException(
208: "Error occured creating templates", e);
209: }
210: }
211:
212: return m_templates;
213: }
214:
215: /**
216: * Finds referenced <code>XSLResource</code>s and adds this instance as
217: * a listener and a dependant.
218: *
219: * @param nodes
220: * @throws ConfigException
221: * @throws DataAccessException
222: * @throws HarmoniseFactoryException
223: */
224: private void handleXSLReferences(NodeList nodes)
225: throws ConfigException, DataAccessException,
226: HarmoniseFactoryException {
227: for (int i = 0; i < nodes.getLength(); i++) {
228: Node node = (Node) nodes.item(i);
229:
230: if (node.getNodeType() == Node.ELEMENT_NODE) {
231: Element el = (Element) node;
232:
233: String sHREF = el.getAttribute(ATTRIB_HREF);
234:
235: if (sHREF != null && sHREF.length() > 0) {
236: String sOHpath = getOHPath(sHREF);
237:
238: XSLResource xsl = (XSLResource) HarmoniseObjectFactory
239: .instantiateHarmoniseObject(m_dsi,
240: XSLResource.class.getName(),
241: sOHpath);
242: if (xsl != null) {
243: xsl.addEditEventListener(this );
244: xsl.addDependant(this );
245: }
246:
247: }
248: }
249: }
250: }
251:
252: /* (non-Javadoc)
253: * @see org.openharmonise.rm.resources.AbstractObject#setIsChanged(boolean)
254: */
255: public void setIsChanged(boolean bIsChanged) {
256: //if something has changed then clear the cached Templates
257: if (bIsChanged == true) {
258: m_templates = null;
259: }
260:
261: super .setIsChanged(bIsChanged);
262: }
263:
264: /**
265: * Returns the output type for this XSLT. Defaults to 'text/plain' if not specified.
266: *
267: * Note: The data is stored in the object's <code>Profile</code> as an instance of
268: * the <code>Property</code> 'OUTPUT'.
269: *
270: * @return
271: */
272: public String getOutputType() throws DataAccessException {
273: String sOutput = DEFAULT_OUTPUT_TYPE;
274:
275: Profile prof = getProfile();
276:
277: try {
278: GeneralPropertyInstance propInst = (GeneralPropertyInstance) prof
279: .getPropertyInstance(PROP_OUTPUT_TYPE);
280:
281: if (propInst != null) {
282: sOutput = (String) propInst.getValue();
283: } else {
284: sOutput = MimeTypeMapping.HTML.getMimeType();
285: }
286: } catch (InvalidPropertyInstanceException e) {
287: throw new DataAccessException(e.getLocalizedMessage(), e);
288: }
289:
290: return sOutput;
291: }
292:
293: /**
294: * Returns the output type for this XSLT. Defaults to 'text/plain' if not specified.
295: *
296: * Note: The data is stored in the object's <code>Profile</code> as an instance of
297: * the <code>Property</code> 'OUTPUT'.
298: *
299: * @return
300: */
301: public void setOutputType(String sOutput) throws PopulateException {
302: try {
303: Profile prof = getProfile();
304:
305: Property outProp = (Property) HarmoniseObjectFactory
306: .instantiateHarmoniseObject(m_dsi, Property.class
307: .getName(), PROP_OUTPUT_TYPE);
308:
309: GeneralPropertyInstance propInst = (GeneralPropertyInstance) prof
310: .getPropertyInstance(PROP_OUTPUT_TYPE);
311:
312: if (propInst != null) {
313: propInst.clearValues();
314: } else {
315: propInst = new GeneralPropertyInstance(m_dsi, outProp,
316: prof);
317: }
318:
319: propInst.addValue(sOutput);
320: } catch (DataAccessException e) {
321: throw new PopulateException(
322: "Error occured getting profile", e);
323: } catch (HarmoniseFactoryException e) {
324: throw new PopulateException(
325: "Error occured getting property from factory", e);
326: } catch (InvalidPropertyValueException e) {
327: throw new PopulateException("Invalid value", e);
328: } catch (InvalidPropertyInstanceException e) {
329: throw new PopulateException("Invalid property", e);
330: }
331:
332: }
333:
334: /* (non-Javadoc)
335: * @see org.openharmonise.rm.resources.content.Asset#createFile()
336: */
337: protected File createFile() throws AssetException, ConfigException,
338: DataAccessException {
339: String sFilePath = null;
340:
341: sFilePath = ConfigSettings.getProperty(XSL_ROOT_PNAME).replace(
342: '/', File.separatorChar);
343:
344: String sName = getName();
345:
346: String sContentType = getContentType();
347: Mapping xsltType = MimeTypeMapping.XSLT;
348: if (xsltType.getMimeTypes().contains(sContentType) == false) {
349: throw new AssetException(
350: "Wrong mime type for this object - " + sContentType);
351: }
352:
353: String sSuffix = xsltType.getExtension();
354:
355: StringBuffer sFullPath = new StringBuffer();
356: sFullPath.append(sFilePath);
357:
358: //check this is not a new file before finding parent
359: if (exists() == true) {
360: AbstractParentObject parent = getRealParent();
361:
362: if (parent != null) {
363:
364: String sParentPath = parent.getFullPath().replace('/',
365: File.separatorChar);
366:
367: String sRootlessPath = sParentPath.substring(ROOT_PATH
368: .length());
369:
370: //ensure file is in the correct
371: if (sRootlessPath.length() > 0) {
372: sFullPath.append(sRootlessPath);
373: }
374: }
375:
376: }
377:
378: sFullPath.append(File.separatorChar);
379:
380: sFullPath.append(sName);
381:
382: if (exists() == false || isLiveVersion() == false) {
383: sFullPath.append("_").append(getKey());
384: }
385:
386: sFullPath.append(".").append(sSuffix);
387:
388: //check path is valid, i.e. that parent exists
389: File test = new File(sFullPath.toString());
390:
391: if (ensureParentExists(test) == false) {
392: throw new AssetException("Trouble creating asset file");
393: }
394:
395: return test;
396: }
397:
398: /* (non-Javadoc)
399: * @see org.openharmonise.rm.resources.lifecycle.Editable#changeStatus(org.openharmonise.rm.resources.lifecycle.Status)
400: */
401: public Editable changeStatus(Status status) throws EditException {
402: Editable result = super .changeStatus(status);
403:
404: try {
405: //need to remove the '_{key}' extension from the file name
406: File oldFile = getContentFile();
407: File newFile = createFile();
408:
409: if (oldFile.equals(newFile) == false) {
410: if (moveFile(oldFile, newFile) == false) {
411: throw new EditException("File manipulation failed");
412: }
413: m_sURI = newFile.getAbsolutePath();
414:
415: m_sURI = getRelativePath(m_sURI);
416:
417: UpdateStatement update = new UpdateStatement();
418:
419: update.addColumnValue(getInstanceColumnRef(
420: Asset.CLMN_URI, isHistorical()), m_sURI);
421:
422: update.addWhereCondition(getInstanceColumnRef(
423: ATTRIB_KEY, isHistorical()), "=", getKey());
424:
425: m_dsi.execute(update);
426: }
427:
428: } catch (DataAccessException e) {
429: throw new EditException(e.getLocalizedMessage(), e);
430: } catch (AssetException e) {
431: throw new EditException(e.getLocalizedMessage(), e);
432: } catch (ConfigException e) {
433: throw new EditException(e.getLocalizedMessage(), e);
434: } catch (DataStoreException e) {
435: throw new EditException(e.getLocalizedMessage(), e);
436: }
437:
438: return result;
439: }
440:
441: /* (non-Javadoc)
442: * @see org.openharmonise.rm.resources.content.Asset#isAssetSavedAsText(java.lang.String)
443: */
444: protected boolean isAssetSavedAsText(String sContentType) {
445: return false;
446: }
447:
448: /* (non-Javadoc)
449: * @see org.openharmonise.rm.resources.content.Asset#setContentType(java.lang.String)
450: */
451: public void setContentType(String sContentType)
452: throws PopulateException {
453:
454: if (MimeTypeMapping.XSLT.getMimeTypes().contains(sContentType) == false) {
455: throw new PopulateException("Invalid content type");
456: }
457:
458: super .setContentType(sContentType);
459: }
460:
461: /* (non-Javadoc)
462: * @see org.openharmonise.rm.resources.lifecycle.Editable#archive()
463: */
464: public Editable archive() throws EditException {
465: XSLResource result = (XSLResource) super .archive();
466:
467: try {
468: //if this was a pending there will be no result
469: if (result != null) {
470:
471: //need to add the '_{key}' extension to the file name
472: File oldFile = getContentFile();
473: File newFile = result.createFile();
474:
475: if (oldFile.equals(newFile) == false) {
476: if (copyFile(oldFile, newFile) == false) {
477: throw new EditException(
478: "File manipulation failed");
479: }
480: m_sURI = newFile.getAbsolutePath();
481:
482: m_sURI = getRelativePath(m_sURI);
483:
484: UpdateStatement update = new UpdateStatement();
485:
486: update.addColumnValue(result.getInstanceColumnRef(
487: Asset.CLMN_URI, result.isHistorical()),
488: m_sURI);
489:
490: update.addWhereCondition(result
491: .getInstanceColumnRef(ATTRIB_KEY, result
492: .isHistorical()), "=", result
493: .getKey());
494:
495: m_dsi.execute(update);
496: }
497: }
498:
499: //remove this object as a listener to other
500: //objects
501: stopListening();
502:
503: } catch (DataAccessException e) {
504: throw new EditException(e.getLocalizedMessage(), e);
505: } catch (AssetException e) {
506: throw new EditException(e.getLocalizedMessage(), e);
507: } catch (ConfigException e) {
508: throw new EditException(e.getLocalizedMessage(), e);
509: } catch (DataStoreException e) {
510: throw new EditException(e.getLocalizedMessage(), e);
511: }
512:
513: return result;
514: }
515:
516: /**
517: * Removes this object as a Listener on other objects
518: *
519: * @throws DataAccessException
520: *
521: */
522: private void stopListening() throws DataAccessException {
523: TransformerFactory factory = TransformerFactory.newInstance();
524: try {
525: File file = getContentFile();
526:
527: StreamSource ssource = new StreamSource(
528: new FileReader(file));
529: ssource.setSystemId(file);
530:
531: m_templates = factory.newTemplates(ssource);
532:
533: try {
534: DocumentBuilderFactory docfactory = DocumentBuilderFactory
535: .newInstance();
536:
537: docfactory.setNamespaceAware(true);
538:
539: DocumentBuilder builder = docfactory
540: .newDocumentBuilder();
541:
542: org.w3c.dom.Document doc = builder.parse(file);
543:
544: NodeList nodes = doc.getDocumentElement()
545: .getElementsByTagNameNS(
546: NamespaceType.XSLT.getURI(),
547: TAG_INCLUDE);
548:
549: stopListeningToXSLResources(nodes);
550:
551: nodes = doc
552: .getDocumentElement()
553: .getElementsByTagNameNS(
554: NamespaceType.XSLT.getURI(), TAG_IMPORT);
555:
556: stopListeningToXSLResources(nodes);
557:
558: //only log errors associated to includes and let
559: //any errors come through when directly accessing
560: //the include XSLTs themselves
561: } catch (ConfigException e) {
562: m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
563: } catch (DataAccessException e) {
564: m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
565: } catch (FactoryConfigurationError e) {
566: m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
567: } catch (ParserConfigurationException e) {
568: m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
569: } catch (SAXException e) {
570: m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
571: } catch (IOException e) {
572: m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
573: } catch (HarmoniseFactoryException e) {
574: m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
575: }
576:
577: } catch (TransformerConfigurationException e) {
578: throw new DataAccessException(
579: "Error occured creating templates", e);
580: } catch (FileNotFoundException e) {
581: throw new DataAccessException(
582: "Error occured creating templates", e);
583: }
584:
585: }
586:
587: /**
588: * Removes this object as a Listener to XSLResources referenced
589: * in the given <code>NodeList</code>
590: *
591: * @param nodes
592: * @throws DataAccessException
593: * @throws ConfigException
594: * @throws HarmoniseFactoryException
595: */
596: private void stopListeningToXSLResources(NodeList nodes)
597: throws ConfigException, DataAccessException,
598: HarmoniseFactoryException {
599: for (int i = 0; i < nodes.getLength(); i++) {
600: Node node = (Node) nodes.item(i);
601:
602: if (node.getNodeType() == Node.ELEMENT_NODE) {
603: Element el = (Element) node;
604:
605: String sHREF = el.getAttribute(ATTRIB_HREF);
606:
607: if (sHREF != null && sHREF.length() > 0) {
608: String sOHpath = getOHPath(sHREF);
609:
610: XSLResource xsl = (XSLResource) HarmoniseObjectFactory
611: .instantiateHarmoniseObject(m_dsi,
612: XSLResource.class.getName(),
613: sOHpath);
614: if (xsl != null) {
615: xsl.removeEditEventListener(this );
616: xsl.removeDependant(this );
617: }
618:
619: }
620: }
621: }
622:
623: }
624:
625: private String getOHPath(File file) throws ConfigException,
626: DataAccessException {
627: String sFilePath = file.getAbsolutePath();
628:
629: return getOHPath(sFilePath);
630: }
631:
632: private String getOHPath(String sFilePath) throws ConfigException,
633: DataAccessException {
634:
635: StringBuffer sBuf = new StringBuffer();
636:
637: int nLastDotIndex = sFilePath.lastIndexOf(".");
638:
639: sFilePath = sFilePath.substring(0, nLastDotIndex);
640:
641: if (isAbsolutePath(sFilePath)) {
642: String sXSLRootFilePath = ConfigSettings
643: .getProperty(XSL_ROOT_PNAME);
644:
645: String sTempPath = sFilePath.substring(sXSLRootFilePath
646: .length());
647:
648: sBuf.append(ROOT_PATH).append(
649: sTempPath.replace(File.separatorChar, '/'));
650: } else {
651: if (sFilePath.startsWith(".." + File.separator)
652: || sFilePath.startsWith("." + File.separator)) {
653:
654: sBuf.append(resolveDots(sFilePath)).append(
655: sFilePath.replace(File.separatorChar, '/'));
656: } else if (sFilePath.startsWith(File.separator)) {
657: //not sure what this'd mean - guess an XSL found in the JVM
658: //root directory?
659: } else {
660: sBuf.append(getPath()).append("/").append(
661: sFilePath.replace(File.separatorChar, '/'));
662: }
663: }
664:
665: return sBuf.toString();
666: }
667:
668: /**
669: * @param sFilePath
670: * @return
671: */
672: private String resolveDots(String sFilePath)
673: throws DataAccessException {
674:
675: StringTokenizer tokenizer = new StringTokenizer(sFilePath);
676:
677: AbstractParentObject parent = this .getRealParent();
678:
679: while (tokenizer.hasMoreTokens()) {
680: String token = tokenizer.nextToken();
681:
682: if (token.equals("..")) {
683: parent = parent.getRealParent();
684: }
685: }
686:
687: return parent.getFullPath();
688: }
689:
690: private String removeDots(String sFilePath) {
691: StringTokenizer tokenizer = new StringTokenizer(sFilePath,
692: File.separator);
693:
694: StringBuffer sbuf = new StringBuffer();
695:
696: while (tokenizer.hasMoreTokens()) {
697: String token = tokenizer.nextToken();
698:
699: if (token.startsWith(".") == false) {
700: sbuf.append("/").append(token);
701: }
702: }
703:
704: return sbuf.toString();
705: }
706:
707: /**
708: * @param sFilePath
709: * @return
710: */
711: private boolean isAbsolutePath(String sFilePath) {
712: boolean bIsAbsolutePath = false;
713: File[] roots = File.listRoots();
714:
715: for (int i = 0; i < roots.length; i++) {
716: if (sFilePath.startsWith(roots[i].getAbsolutePath())) {
717: bIsAbsolutePath = true;
718: break;
719: }
720: }
721:
722: return bIsAbsolutePath;
723: }
724:
725: /* (non-Javadoc)
726: * @see org.openharmonise.rm.resources.lifecycle.EditEventListener#workflowObjectArchived(org.openharmonise.rm.resources.lifecycle.EditEvent)
727: */
728: public void workflowObjectArchived(EditEvent event) {
729: Object src = event.getSource();
730:
731: if (event.getSource() instanceof XSLResource) {
732: m_templates = null;
733:
734: XSLResource xsl = (XSLResource) src;
735:
736: xsl.removeEditEventListener(this );
737: }
738:
739: super .workflowObjectArchived(event);
740: }
741:
742: /* (non-Javadoc)
743: * @see org.openharmonise.commons.cache.DependableCacheObject#hasDependants()
744: */
745: public boolean hasDependants() {
746: return (m_dependants != null && m_dependants.size() > 0);
747: }
748:
749: /* (non-Javadoc)
750: * @see org.openharmonise.commons.cache.DependableCacheObject#addDependant(org.openharmonise.commons.cache.CacheDependant)
751: */
752: public void addDependant(CacheDependant dep) {
753: if (m_dependants == null) {
754: m_dependants = new WeakHashSet();
755: }
756:
757: if (m_dependants.contains(dep) == false) {
758: m_dependants.add(dep);
759: }
760: }
761:
762: /* (non-Javadoc)
763: * @see org.openharmonise.commons.cache.DependableCacheObject#removeDependant(org.openharmonise.commons.cache.CacheDependant)
764: */
765: public void removeDependant(CacheDependant dep) {
766: if (m_dependants != null) {
767: m_dependants.remove(dep);
768: }
769:
770: }
771:
772: /* (non-Javadoc)
773: * @see org.openharmonise.rm.resources.content.Asset#setIsContentChanged(boolean)
774: */
775: public void setIsContentChanged(boolean bContentChanged) {
776: if (bContentChanged == true) {
777: m_templates = null;
778: }
779: super .setIsContentChanged(bContentChanged);
780: }
781:
782: /* (non-Javadoc)
783: * @see org.openharmonise.rm.resources.content.Asset#getAssetRoot()
784: */
785: public String getAssetRoot() throws DataAccessException {
786: String sRoot = null;
787:
788: try {
789: sRoot = ConfigSettings.getProperty(XSL_ROOT_PNAME);
790: } catch (ConfigException e) {
791: throw new DataAccessException(e);
792: }
793:
794: return sRoot;
795: }
796:
797: /* (non-Javadoc)
798: * @see org.openharmonise.rm.resources.content.Asset#setContentFile(java.io.File)
799: */
800: public void setContentFile(File assetFile) throws PopulateException {
801: m_templates = null;
802: super.setContentFile(assetFile);
803: }
804: }
|