001: // $HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/framework/xml/XMLFragment.java $
002: /*---------------- FILE HEADER ------------------------------------------
003:
004: This file is part of deegree.
005: Copyright (C) 2001-2008 by:
006: EXSE, Department of Geography, University of Bonn
007: http://www.giub.uni-bonn.de/deegree/
008: lat/lon GmbH
009: http://www.lat-lon.de
010:
011: This library is free software; you can redistribute it and/or
012: modify it under the terms of the GNU Lesser General Public
013: License as published by the Free Software Foundation; either
014: version 2.1 of the License, or (at your option) any later version.
015:
016: This library is distributed in the hope that it will be useful,
017: but WITHOUT ANY WARRANTY; without even the implied warranty of
018: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019: Lesser General Public License for more details.
020:
021: You should have received a copy of the GNU Lesser General Public
022: License along with this library; if not, write to the Free Software
023: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024:
025: Contact:
026:
027: Andreas Poth
028: lat/lon GmbH
029: Aennchenstr. 19
030: 53115 Bonn
031: Germany
032: E-Mail: poth@lat-lon.de
033:
034: Prof. Dr. Klaus Greve
035: Department of Geography
036: University of Bonn
037: Meckenheimer Allee 166
038: 53115 Bonn
039: Germany
040: E-Mail: greve@giub.uni-bonn.de
041:
042:
043: ---------------------------------------------------------------------------*/
044:
045: package org.deegree.framework.xml;
046:
047: import java.io.File;
048: import java.io.IOException;
049: import java.io.InputStream;
050: import java.io.InputStreamReader;
051: import java.io.OutputStream;
052: import java.io.PushbackInputStream;
053: import java.io.PushbackReader;
054: import java.io.Reader;
055: import java.io.Serializable;
056: import java.io.StringWriter;
057: import java.io.Writer;
058: import java.net.MalformedURLException;
059: import java.net.URI;
060: import java.net.URISyntaxException;
061: import java.net.URL;
062: import java.util.HashMap;
063: import java.util.Map;
064: import java.util.NoSuchElementException;
065: import java.util.Properties;
066: import java.util.StringTokenizer;
067:
068: import javax.xml.parsers.DocumentBuilder;
069: import javax.xml.parsers.DocumentBuilderFactory;
070: import javax.xml.parsers.ParserConfigurationException;
071: import javax.xml.transform.OutputKeys;
072: import javax.xml.transform.Source;
073: import javax.xml.transform.Transformer;
074: import javax.xml.transform.TransformerConfigurationException;
075: import javax.xml.transform.TransformerException;
076: import javax.xml.transform.TransformerFactory;
077: import javax.xml.transform.dom.DOMSource;
078: import javax.xml.transform.stream.StreamResult;
079:
080: import org.deegree.datatypes.QualifiedName;
081: import org.deegree.datatypes.xlink.SimpleLink;
082: import org.deegree.framework.log.ILogger;
083: import org.deegree.framework.log.LoggerFactory;
084: import org.deegree.framework.util.BootLogger;
085: import org.deegree.framework.util.CharsetUtils;
086: import org.deegree.framework.util.StringTools;
087: import org.deegree.model.feature.Messages;
088: import org.deegree.ogcbase.CommonNamespaces;
089: import org.w3c.dom.Document;
090: import org.w3c.dom.Element;
091: import org.w3c.dom.NamedNodeMap;
092: import org.w3c.dom.Node;
093: import org.xml.sax.InputSource;
094: import org.xml.sax.SAXException;
095:
096: /**
097: * An instance of <code>XMLFragment</code> encapsulates an underlying {@link Element} which acts
098: * as the root element of the document (which may be a fragment or a whole document).
099: * <p>
100: * Basically, <code>XMLFragment</code> provides easy loading and proper saving (automatically
101: * generated CDATA-elements for text nodes that need to be escaped) and acts as base class for all
102: * XML parsers in deegree.
103: *
104: * TODO: automatically generated CDATA-elements are not implemented yet
105: *
106: * <p>
107: * Additionally, <code>XMLFragment</code> tries to make the handling of relative paths inside the
108: * document's content as painless as possible. This means that after initialization of the
109: * <code>XMLFragment</code> with the correct SystemID (i.e. the URL of the document):
110: * <ul>
111: * <li>external parsed entities (in the DOCTYPE part) can use relative URLs; e.g. <!ENTITY local
112: * SYSTEM "conf/wfs/wfs.cfg"></li>
113: * <li>application specific documents which extend <code>XMLFragment</code> can resolve relative
114: * URLs during parsing by calling the <code>resolve()</code> method</li>
115: * </ul>
116: *
117: * @author <a href="mailto:tfr@users.sourceforge.net">Torsten Friebe </a>
118: * @author <a href="mailto:schneider@lat-lon.de">Markus Schneider </a>
119: * @author last edited by: $Author: rbezema $
120: *
121: * @version $Revision: 10106 $, $Date: 2008-02-18 04:58:04 -0800 (Mon, 18 Feb 2008) $
122: *
123: * @see org.deegree.framework.xml.XMLTools
124: */
125:
126: public class XMLFragment implements Serializable {
127:
128: private static final long serialVersionUID = 8984447437613709386L;
129:
130: protected static NamespaceContext nsContext = CommonNamespaces
131: .getNamespaceContext();
132:
133: protected static final URI XLNNS = CommonNamespaces.XLNNS;
134:
135: private static final ILogger LOG = LoggerFactory
136: .getLogger(XMLFragment.class);
137:
138: /**
139: * Use this URL as SystemID only if an <code>XMLFragment</code> cannot be pinpointed to a URL -
140: * in this case it may not use any relative references!
141: */
142: public static final String DEFAULT_URL = "http://www.deegree.org";
143:
144: private URL systemId;
145:
146: private Element rootElement;
147:
148: private static final String PRETTY_PRINTER_RESOURCE = "PrettyPrinter.xsl";
149:
150: private static XSLTDocument PRETTY_PRINTER_XSLT = new XSLTDocument();
151:
152: static {
153: LOG
154: .logDebug("DOM implementation in use (DocumentBuilderFactory): "
155: + DocumentBuilderFactory.newInstance()
156: .getClass().getName());
157: try {
158: LOG
159: .logDebug("DOM implementation in use (DocumentBuilder): "
160: + DocumentBuilderFactory.newInstance()
161: .newDocumentBuilder().getClass()
162: .getName());
163: } catch (Exception e) {
164: BootLogger.logError(
165: "Error creating test DocumentBuilder instance.", e);
166: }
167: try {
168: URL url = XMLFragment.class
169: .getResource(PRETTY_PRINTER_RESOURCE);
170: if (url == null) {
171: throw new IOException("The resource '"
172: + PRETTY_PRINTER_RESOURCE
173: + " could not be found.");
174: }
175: PRETTY_PRINTER_XSLT.load(url);
176: } catch (Exception e) {
177: BootLogger.logError(
178: "Error loading PrettyPrinter-XSLT document: "
179: + e.getMessage(), e);
180: }
181: }
182:
183: /**
184: * Creates a new <code>XMLFragment</code> which is not initialized.
185: */
186: public XMLFragment() {
187: // nothing to do
188: }
189:
190: /**
191: * Creates a new <code>XMLFragment</code> which is loaded from the given <code>URL</code>.
192: *
193: * @param url
194: * @throws IOException
195: * @throws SAXException
196: */
197: public XMLFragment(URL url) throws IOException, SAXException {
198: load(url);
199: }
200:
201: /**
202: * Creates a new <code>XMLFragment</code> which is loaded from the given <code>File</code>.
203: *
204: * @param file
205: * the file to load from
206: * @throws SAXException
207: * if the document could not be parsed
208: * @throws IOException
209: * if the document could not be read
210: * @throws MalformedURLException
211: * if the file cannot be transposed to a valid url
212: */
213: public XMLFragment(File file) throws MalformedURLException,
214: IOException, SAXException {
215: if (file != null) {
216: load(file.toURI().toURL());
217: }
218: }
219:
220: /**
221: * Creates a new <code>XMLFragment</code> which is loaded from the given <code>Reader</code>.
222: *
223: * @param reader
224: * @param systemId
225: * this string should represent a URL that is related to the passed reader. If this
226: * URL is not available or unknown, the string should contain the value of
227: * XMLFragment.DEFAULT_URL
228: * @throws SAXException
229: * @throws IOException
230: */
231: public XMLFragment(Reader reader, String systemId)
232: throws SAXException, IOException {
233: load(reader, systemId);
234: }
235:
236: /**
237: * Creates a new <code>XMLFragment</code> instance based on the submitted
238: * <code>Document</code>.
239: *
240: * @param doc
241: * @param systemId
242: * this string should represent a URL that is the source of the passed doc. If this
243: * URL is not available or unknown, the string should contain the value of
244: * XMLFragment.DEFAULT_URL
245: * @throws MalformedURLException
246: * if systemId is no valid and absolute <code>URL</code>
247: */
248: public XMLFragment(Document doc, String systemId)
249: throws MalformedURLException {
250: setRootElement(doc.getDocumentElement());
251: setSystemId(systemId);
252: }
253:
254: /**
255: * Creates a new <code>XMLFragment</code> instance based on the submitted <code>Element</code>.
256: *
257: * @param element
258: */
259: public XMLFragment(Element element) {
260: setRootElement(element);
261: }
262:
263: /**
264: * Constructs an empty document with the given <code>QualifiedName</code> as root node.
265: *
266: * @param elementName
267: * if the name's namespace is set, the prefix should be set as well.
268: */
269: public XMLFragment(QualifiedName elementName) {
270: try {
271: DocumentBuilder db = DocumentBuilderFactory.newInstance()
272: .newDocumentBuilder();
273: if (elementName.getNamespace() == null) {
274: rootElement = db.newDocument().createElement(
275: elementName.getLocalName());
276: } else {
277: String pre = elementName.getPrefix();
278: String ns = elementName.getNamespace().toString();
279: if (pre == null || pre.trim().length() == 0) {
280: pre = "dummy";
281: LOG.logWarning(StringTools.concat(200,
282: "Incorrect usage of deegree API,",
283: " prefix of a root node was not ",
284: "defined:\nNode name was ", elementName
285: .getLocalName(),
286: ", namespace was ", ns));
287: }
288: String name = StringTools.concat(200, pre, ":",
289: elementName.getLocalName());
290: rootElement = db.newDocument()
291: .createElementNS(ns, name);
292: rootElement.setAttribute("xmlns:" + pre, ns);
293: }
294: } catch (ParserConfigurationException e) {
295: LOG
296: .logError(
297: "The parser seems to be misconfigured. Broken installation?",
298: e);
299: }
300: }
301:
302: /**
303: * Returns the systemId (the URL of the <code>XMLFragment</code>).
304: *
305: * @return the systemId
306: */
307: public URL getSystemId() {
308: return systemId;
309: }
310:
311: /**
312: * @param systemId
313: * The systemId (physical location) to set (may be null).
314: * @throws MalformedURLException
315: */
316: public void setSystemId(String systemId)
317: throws MalformedURLException {
318: if (systemId != null) {
319: this .systemId = new URL(systemId);
320: }
321: }
322:
323: /**
324: * @param systemId
325: * The systemId (physical location) to set.
326: */
327: public void setSystemId(URL systemId) {
328: this .systemId = systemId;
329: }
330:
331: /**
332: * Returns whether the document has a schema reference.
333: *
334: * @return true, if the document has a schema reference, false otherwise
335: */
336: public boolean hasSchema() {
337: if (this .rootElement.getAttribute("xsi:schemaLocation") != null) {
338: return true;
339: }
340: return false;
341: }
342:
343: /**
344: * Determines the namespace <code>URI</code>s and the bound schema <code>URL</code>s from
345: * the 'xsi:schemaLocation' attribute of the document element.
346: *
347: * @return keys are URIs (namespaces), values are URLs (schema locations)
348: * @throws XMLParsingException
349: */
350: public Map<URI, URL> getAttachedSchemas()
351: throws XMLParsingException {
352:
353: Map<URI, URL> schemaMap = new HashMap<URI, URL>();
354:
355: NamedNodeMap attrMap = rootElement.getAttributes();
356: Node schemaLocationAttr = attrMap
357: .getNamedItem("xsi:schemaLocation");
358: if (schemaLocationAttr == null) {
359: return schemaMap;
360: }
361:
362: String target = schemaLocationAttr.getNodeValue();
363: StringTokenizer tokenizer = new StringTokenizer(target);
364:
365: while (tokenizer.hasMoreTokens()) {
366: URI nsURI = null;
367: String token = tokenizer.nextToken();
368: try {
369: nsURI = new URI(token);
370: } catch (URISyntaxException e) {
371: String msg = "Invalid 'xsi:schemaLocation' attribute: namespace "
372: + token + "' is not a valid URI.";
373: LOG.logError(msg);
374: throw new XMLParsingException(msg);
375: }
376:
377: URL schemaURL = null;
378: try {
379: token = tokenizer.nextToken();
380: schemaURL = resolve(token);
381: } catch (NoSuchElementException e) {
382: String msg = "Invalid 'xsi:schemaLocation' attribute: namespace '"
383: + nsURI + "' is missing a schema URL.";
384: LOG.logError(msg);
385: throw new XMLParsingException(msg);
386: } catch (MalformedURLException ex) {
387: String msg = "Invalid 'xsi:schemaLocation' attribute: '"
388: + token
389: + "' for namespace '"
390: + nsURI
391: + "' could not be parsed as URL.";
392: throw new XMLParsingException(msg);
393: }
394: schemaMap.put(nsURI, schemaURL);
395: }
396: return schemaMap;
397: }
398:
399: /**
400: * Initializes the <code>XMLFragment</code> with the content from the given <code>URL</code>.
401: * Sets the SystemId, too.
402: *
403: * @param url
404: * @throws IOException
405: * @throws SAXException
406: */
407: public void load(URL url) throws IOException, SAXException {
408: String uri = url.toExternalForm();
409: load(url.openStream(), uri);
410: }
411:
412: /**
413: * Initializes the <code>XMLFragment</code> with the content from the given
414: * <code>InputStream</code>. Sets the SystemId, too.
415: *
416: * @param istream
417: * @param systemId
418: * cannot be null. This string should represent a URL that is related to the passed
419: * istream. If this URL is not available or unknown, the string should contain the
420: * value of XMLFragment.DEFAULT_URL
421: * @throws SAXException
422: * @throws IOException
423: * @throws XMLException
424: * @throws NullPointerException
425: */
426: public void load(InputStream istream, String systemId)
427: throws SAXException, IOException, XMLException {
428:
429: PushbackInputStream pbis = new PushbackInputStream(istream,
430: 1024);
431: String encoding = readEncoding(pbis);
432:
433: InputStreamReader isr = new InputStreamReader(pbis, encoding);
434: load(isr, systemId);
435: }
436:
437: /**
438: * reads the encoding of a XML document from its header. If no header available
439: * <code>CharsetUtils.getSystemCharset()</code> will be returned
440: *
441: * @param pbis
442: * @return encoding of a XML document
443: * @throws IOException
444: */
445: private String readEncoding(PushbackInputStream pbis)
446: throws IOException {
447: byte[] b = new byte[80];
448: int rd = pbis.read(b);
449: String s = new String(b).toLowerCase();
450: String encoding = CharsetUtils.getSystemCharset();
451: if (s.indexOf("?>") > -1) {
452: int p = s.indexOf("encoding=");
453: if (p > -1) {
454: StringBuffer sb = new StringBuffer();
455: int k = p + 1 + "encoding=".length();
456: while (s.charAt(k) != '"' && s.charAt(k) != '\'') {
457: sb.append(s.charAt(k++));
458: }
459: encoding = sb.toString();
460: }
461: }
462: pbis.unread(b, 0, rd);
463: return encoding;
464: }
465:
466: /**
467: * Initializes the <code>XMLFragment</code> with the content from the given
468: * <code>Reader</code>. Sets the SystemId, too.
469: *
470: * @param reader
471: * @param systemId
472: * can not be null. This string should represent a URL that is related to the passed
473: * reader. If this URL is not available or unknown, the string should contain the
474: * value of XMLFragment.DEFAULT_URL
475: * @throws SAXException
476: * @throws IOException
477: * @throws NullPointerException
478: */
479: public void load(Reader reader, String systemId)
480: throws SAXException, IOException {
481:
482: PushbackReader pbr = new PushbackReader(reader, 1024);
483: int c = pbr.read();
484: if (c != 65279 && c != 65534) {
485: // no BOM! push char back into reader
486: pbr.unread(c);
487: }
488:
489: InputSource source = new InputSource(pbr);
490: if (systemId == null) {
491: throw new NullPointerException(
492: "'systemId' must not be null!");
493: }
494: setSystemId(systemId);
495: DocumentBuilder builder = XMLTools.getDocumentBuilder();
496: Document doc = builder.parse(source);
497: setRootElement(doc.getDocumentElement());
498: }
499:
500: /**
501: * @param rootElement
502: */
503: public void setRootElement(Element rootElement) {
504: this .rootElement = rootElement;
505: }
506:
507: /**
508: * @return the element
509: */
510: public Element getRootElement() {
511: return rootElement;
512: }
513:
514: /**
515: * Resolves the given URL (which may be relative) against the SystemID of the
516: * <code>XMLFragment</code> into a <code>URL</code> (which is always absolute).
517: *
518: * @param url
519: * @return the resolved URL object
520: * @throws MalformedURLException
521: */
522: public URL resolve(String url) throws MalformedURLException {
523: LOG.logDebug(StringTools.concat(200, "Resolving URL '", url,
524: "' against SystemID '", systemId, "' of XMLFragment"));
525: // check if url is an absolut path
526: File file = new File(url);
527: if (file.isAbsolute()) {
528: return file.toURL();
529: }
530: // remove leading '/' because otherwise
531: // URL resolvedURL = new URL( systemId, url ); will fail
532: if (url.startsWith("/")) {
533: url = url.substring(1, url.length());
534: LOG
535: .logInfo("URL has been corrected by removing the leading '/'");
536: }
537: URL resolvedURL = new URL(systemId, url);
538:
539: LOG.logDebug(StringTools.concat(100, "-> resolvedURL: '",
540: resolvedURL, "'"));
541: return resolvedURL;
542: }
543:
544: /**
545: * Writes the <code>XMLFragment</code> instance to the given <code>Writer</code> using the
546: * default system encoding and adding CDATA-sections in for text-nodes where needed.
547: *
548: * TODO: Add code for CDATA safety.
549: *
550: * @param writer
551: */
552: public void write(Writer writer) {
553: Properties properties = new Properties();
554: properties.setProperty(OutputKeys.ENCODING, CharsetUtils
555: .getSystemCharset());
556: write(writer, properties);
557: }
558:
559: /**
560: * Writes the <code>XMLFragment</code> instance to the given <code>Writer</code> using the
561: * specified <code>OutputKeys</code>.
562: *
563: * @param writer
564: * cannot be null
565: * @param outputProperties
566: * output properties for the <code>Transformer</code> that is used to serialize the
567: * document
568: *
569: * see javax.xml.OutputKeys
570: */
571: public void write(Writer writer, Properties outputProperties) {
572: try {
573: Source source = new DOMSource(rootElement);
574: Transformer transformer = TransformerFactory.newInstance()
575: .newTransformer();
576: if (outputProperties != null) {
577: transformer.setOutputProperties(outputProperties);
578: }
579: transformer.transform(source, new StreamResult(writer));
580: } catch (TransformerConfigurationException e) {
581: LOG.logError(e.getMessage(), e);
582: throw new XMLException(e);
583: } catch (Exception e) {
584: LOG.logError(e.getMessage(), e);
585: throw new XMLException(e);
586: }
587: }
588:
589: /**
590: * Writes the <code>XMLFragment</code> instance to the given <code>OutputStream</code> using
591: * the default system encoding and adding CDATA-sections in for text-nodes where needed.
592: *
593: * TODO: Add code for CDATA safety.
594: *
595: * @param os
596: */
597: public void write(OutputStream os) {
598: Properties properties = new Properties();
599: properties.setProperty(OutputKeys.ENCODING, CharsetUtils
600: .getSystemCharset());
601: write(os, properties);
602: }
603:
604: /**
605: * Writes the <code>XMLFragment</code> instance to the given <code>OutputStream</code> using
606: * the specified <code>OutputKeys</code> which allow complete control of the generated output.
607: *
608: * @param os
609: * cannot be null
610: * @param outputProperties
611: * output properties for the <code>Transformer</code> used to serialize the
612: * document
613: *
614: * @see javax.xml.transform.OutputKeys
615: */
616: public void write(OutputStream os, Properties outputProperties) {
617: try {
618: Source source = new DOMSource(rootElement);
619: Transformer transformer = TransformerFactory.newInstance()
620: .newTransformer();
621: if (outputProperties != null) {
622: transformer.setOutputProperties(outputProperties);
623: }
624: transformer.transform(source, new StreamResult(os));
625: } catch (TransformerConfigurationException e) {
626: LOG.logError(e.getMessage(), e);
627: throw new XMLException(e);
628: } catch (Exception e) {
629: LOG.logError(e.getMessage(), e);
630: throw new XMLException(e);
631: }
632: }
633:
634: /**
635: * Writes the <code>XMLFragment</code> instance to the given <code>OutputStream</code> using
636: * indentation so it may be read easily.
637: *
638: * @param os
639: * @throws TransformerException
640: */
641: public void prettyPrint(OutputStream os)
642: throws TransformerException {
643: PRETTY_PRINTER_XSLT.transform(this ).write(os);
644: }
645:
646: /**
647: * Writes the <code>XMLFragment</code> instance to the given <code>Writer</code> using
648: * indentation so it may be read easily.
649: *
650: * @param writer
651: * @throws TransformerException
652: */
653: public void prettyPrint(Writer writer) throws TransformerException {
654: PRETTY_PRINTER_XSLT.transform(this ).write(writer);
655: }
656:
657: /**
658: * Parses the submitted <code>Element</code> as a <code>SimpleLink</code>.
659: * <p>
660: * Possible escaping of the attributes "xlink:href", "xlink:role" and "xlink:arcrole" is
661: * performed automatically.
662: * </p>
663: *
664: * @param element
665: * @return the object representation of the element
666: * @throws XMLParsingException
667: */
668: protected SimpleLink parseSimpleLink(Element element)
669: throws XMLParsingException {
670:
671: URI href = null;
672: URI role = null;
673: URI arcrole = null;
674: String title = null;
675: String show = null;
676: String actuate = null;
677:
678: String uriString = null;
679: try {
680: uriString = XMLTools.getNodeAsString(element,
681: "@xlink:href", nsContext, null);
682: if (uriString != null) {
683: href = new URI(null, uriString, null);
684: }
685: uriString = XMLTools.getNodeAsString(element,
686: "@xlink:role", nsContext, null);
687: if (uriString != null) {
688: role = new URI(null, uriString, null);
689: }
690: uriString = XMLTools.getNodeAsString(element,
691: "@xlink:arcrole", nsContext, null);
692: if (uriString != null) {
693: arcrole = new URI(null, uriString, null);
694: }
695: } catch (URISyntaxException e) {
696: throw new XMLParsingException("'" + uriString
697: + "' is not a valid URI.");
698: }
699:
700: return new SimpleLink(href, role, arcrole, title, show, actuate);
701: }
702:
703: /**
704: * Parses the value of the submitted <code>Node</code> as a <code>QualifiedName</code>.
705: * <p>
706: * To parse the text contents of an <code>Element</code> node, the actual text node must be
707: * given, not the <code>Element</code> node itself.
708: * </p>
709: *
710: * @param node
711: * @return object representation of the element
712: * @throws XMLParsingException
713: */
714: public static QualifiedName parseQualifiedName(Node node)
715: throws XMLParsingException {
716:
717: String name = node.getNodeValue().trim();
718: QualifiedName qName = null;
719: if (name.indexOf(':') > -1) {
720: String[] tmp = StringTools.toArray(name, ":", false);
721: try {
722: qName = new QualifiedName(tmp[0], tmp[1], XMLTools
723: .getNamespaceForPrefix(tmp[0], node));
724: } catch (URISyntaxException e) {
725: throw new XMLParsingException(e.getMessage(), e);
726: }
727: } else {
728: qName = new QualifiedName(name);
729: }
730: return qName;
731: }
732:
733: /**
734: * Returns the qualified name of the given element.
735: *
736: * @param element
737: * @return the qualified name of the given element.
738: * @throws XMLParsingException
739: */
740: protected QualifiedName getQualifiedName(Element element)
741: throws XMLParsingException {
742:
743: // TODO check if we can use element.getNamespaceURI() instead
744: URI nsURI = null;
745: String prefix = element.getPrefix();
746: try {
747: nsURI = XMLTools.getNamespaceForPrefix(prefix, element);
748: } catch (URISyntaxException e) {
749: String msg = Messages.format("ERROR_NSURI_NO_URI", element
750: .getPrefix());
751: LOG.logError(msg, e);
752: throw new XMLParsingException(msg, e);
753: }
754: QualifiedName ftName = new QualifiedName(prefix, element
755: .getLocalName(), nsURI);
756:
757: return ftName;
758: }
759:
760: /**
761: * Returns a string representation of the XML Document
762: *
763: * @return the string
764: */
765: public String getAsString() {
766: StringWriter writer = new StringWriter(50000);
767: Source source = new DOMSource(rootElement);
768: try {
769: Transformer transformer = TransformerFactory.newInstance()
770: .newTransformer();
771: transformer.setOutputProperty("encoding", CharsetUtils
772: .getSystemCharset());
773: transformer.transform(source, new StreamResult(writer));
774: } catch (Exception e) {
775: LOG.logError("Error serializing XMLFragment!", e);
776: }
777: return writer.toString();
778: }
779:
780: /**
781: * Returns a string representation of the XML Document, pretty printed. Note that pretty
782: * printing can mess up XML documents in some cases (GML, for instance).
783: *
784: * @return the string
785: */
786: public String getAsPrettyString() {
787: StringWriter writer = new StringWriter(50000);
788: try {
789: prettyPrint(writer);
790: } catch (TransformerException e) {
791: LOG.logError("Error pretty printing XMLFragment!", e);
792: }
793: return writer.toString();
794: }
795:
796: /**
797: * Returns a string representation of the object.
798: *
799: * @return a string representation of the object.
800: */
801: @Override
802: public String toString() {
803: return getAsString();
804: }
805: }
|